Bạn có thể buộc một thành phần React để đăng ký lại mà không cần gọi setState không?


688

Tôi có một đối tượng bên ngoài (đối với thành phần) mà tôi muốn lắng nghe để thay đổi. Khi đối tượng được cập nhật, nó sẽ phát ra các sự kiện thay đổi, và sau đó tôi muốn chạy lại thành phần khi phát hiện bất kỳ thay đổi nào.

Với mức cao nhất, React.renderđiều này là có thể, nhưng trong một thành phần, nó không hoạt động (điều này có ý nghĩa vì renderphương thức chỉ trả về một đối tượng).

Đây là một ví dụ mã:

export default class MyComponent extends React.Component {

  handleButtonClick() {
    this.render();
  }

  render() {
    return (
      <div>
        {Math.random()}
        <button onClick={this.handleButtonClick.bind(this)}>
          Click me
        </button>
      </div>
    )
  }
}

Nhấp vào nút gọi nội bộ this.render(), nhưng đó không phải là điều thực sự khiến kết xuất xảy ra (bạn có thể thấy điều này trong thực tế vì văn bản được tạo bởi {Math.random()}không thay đổi). Tuy nhiên, nếu tôi chỉ đơn giản gọi this.setState()thay vì this.render(), nó hoạt động tốt.

Vì vậy, tôi đoán câu hỏi của tôi là: các thành phần React cần phải có trạng thái để đăng ký lại? Có cách nào để buộc thành phần cập nhật theo yêu cầu mà không thay đổi trạng thái không?


7
các câu trả lời được chấp nhận nói this.forceUpdate()là giải pháp phù hợp trong khi phần còn lại của tất cả các câu trả lời và một số ý kiến là không nên sử dụng forceUpdate(). Điều đó có ổn không khi nói rằng câu hỏi chưa có giải pháp / câu trả lời phù hợp?
adi

6
Câu trả lời bị loại trừ đã trả lời câu hỏi của tôi tại thời điểm đó. Về mặt kỹ thuật là câu trả lời tôi đang tìm kiếm, và tôi vẫn nghĩ câu trả lời đúng. Các câu trả lời khác tôi nghĩ là thông tin bổ sung tốt cho những người có cùng câu hỏi cần lưu ý.
Philip Walton

Điều thú vị cần lưu ý là bạn KHÔNG CẦN BẤT CỨ LÚC NÀO ngoài việc khởi tạo nó thành một đối tượng đơn giản, sau đó gọi this.setState ({}) chỉ kích hoạt kết xuất mới. Phản ứng là tuyệt vời nhưng đôi khi cũng kỳ lạ. Do đó, bạn có thể trực tiếp lặp qua dữ liệu lưu trữ khi kích hoạt thay đổi mà không cần thêm hệ thống ống nước hoặc lo lắng về dữ liệu trên mỗi phiên bản thành phần.
Jason Sebring

Nhìn chung, tôi sẽ nói có. Nếu bạn đang sử dụng cập nhật vũ lực thì đây là để cập nhật các thành phần nơi chúng có thể phụ thuộc vào các thay đổi bên ngoài quản lý trạng thái của ứng dụng của bạn. Tôi không thể nghĩ ra một ví dụ tốt về điều đó. Hữu ích để biết mặc dù.
Daniel

Câu trả lời:


765

Trong thành phần của bạn, bạn có thể gọi this.forceUpdate()để buộc một rerender.

Tài liệu: https://facebook.github.io/react/docs/component-api.html


168
Một cách khác là this.setState (this.state);
kar

25
Sử dụng Forceupdate không được khuyến khích, vui lòng xem câu trả lời cuối cùng.
Varand Pezeshkian

42
Mặc dù this.forceUpdate()không phải là một giải pháp rất tốt cho vấn đề của người hỏi, nhưng đó là câu trả lời chính xác cho câu hỏi được đặt ra trong tiêu đề. Mặc dù nói chung nên tránh, có những tình huống khi ForceUpdate là một giải pháp tốt.
ArneHugo

8
@kar Trên thực tế, logic bổ sung có thể được thực hiện trong shouldComponentUpdate()việc hiển thị giải pháp của bạn vô ích.
Qwerty

4

326

forceUpdatenên tránh vì nó đi chệch khỏi lối tư duy React. Các tài liệu React trích dẫn một ví dụ về thời điểm forceUpdatecó thể được sử dụng:

Theo mặc định, khi trạng thái hoặc đạo cụ của thành phần thay đổi, thành phần của bạn sẽ kết xuất lại. Tuy nhiên, nếu những thay đổi này hoàn toàn (ví dụ: dữ liệu sâu bên trong một đối tượng thay đổi mà không thay đổi chính đối tượng) hoặc nếu phương thức render () của bạn phụ thuộc vào một số dữ liệu khác, bạn có thể nói với React rằng nó cần chạy lại render () bằng cách gọi buộcUpdate ().

Tuy nhiên, tôi muốn đề xuất ý tưởng rằng ngay cả với các đối tượng được lồng sâu, forceUpdatelà không cần thiết. Bằng cách sử dụng một thay đổi theo dõi nguồn dữ liệu bất biến trở nên rẻ tiền; một thay đổi sẽ luôn dẫn đến một đối tượng mới, vì vậy chúng ta chỉ cần kiểm tra xem tham chiếu đến đối tượng đã thay đổi hay chưa. Bạn có thể sử dụng thư viện JS bất biến để triển khai các đối tượng dữ liệu bất biến vào ứng dụng của bạn.

Thông thường, bạn nên cố gắng tránh tất cả các sử dụng của ForceUpdate () và chỉ đọc từ this.props và this.state trong render (). Điều này làm cho thành phần của bạn "thuần túy" và ứng dụng của bạn đơn giản và hiệu quả hơn nhiều. ForceUpdate ()

Thay đổi khóa của phần tử bạn muốn kết xuất lại sẽ hoạt động. Đặt prop prop trên phần tử của bạn thông qua trạng thái và sau đó khi bạn muốn cập nhật trạng thái thiết lập để có một khóa mới.

<Element key={this.state.key} /> 

Sau đó, một sự thay đổi xảy ra và bạn đặt lại khóa

this.setState({ key: Math.random() });

Tôi muốn lưu ý rằng điều này sẽ thay thế phần tử mà khóa đang thay đổi. Một ví dụ về nơi điều này có thể hữu ích là khi bạn có trường nhập tệp mà bạn muốn đặt lại sau khi tải lên hình ảnh.

Mặc dù câu trả lời thực sự cho câu hỏi của OP là forceUpdate()tôi đã thấy giải pháp này hữu ích trong các tình huống khác nhau. Tôi cũng muốn lưu ý rằng nếu bạn thấy mình đang sử dụng, forceUpdatebạn có thể muốn xem lại mã của mình và xem liệu có cách nào khác để làm việc không.

CHÚ THÍCH 1-9-2019:

Ở trên (thay đổi phím) sẽ thay thế hoàn toàn phần tử. Nếu bạn thấy mình cập nhật khóa để thực hiện thay đổi, có thể bạn đã gặp sự cố ở một nơi khác trong mã của mình. Sử dụng Math.random()phím in sẽ tạo lại thành phần với mỗi kết xuất. Tôi sẽ KHÔNG khuyên bạn nên cập nhật khóa như thế này vì phản ứng sử dụng khóa để xác định cách tốt nhất để kết xuất lại mọi thứ.


16
Tôi muốn biết lý do tại sao điều này có một downvote? Tôi đã đập đầu mình để cố gắng để các trình đọc màn hình phản hồi lại các cảnh báo aria và đây là kỹ thuật duy nhất tôi thấy hoạt động đáng tin cậy. Nếu bạn có một cái gì đó trong giao diện người dùng của bạn tạo ra cảnh báo tương tự mỗi lần nhấp vào, theo mặc định, phản ứng không hiển thị lại DOM để trình đọc màn hình không thông báo thay đổi. Đặt một khóa duy nhất làm cho nó hoạt động. Có lẽ downvote là vì nó vẫn liên quan đến việc thiết lập trạng thái. Nhưng việc buộc kết xuất lại vào DOM bằng cách cài đặt khóa là vàng!
Martin Bayly

2
Tôi rất thích câu trả lời này vì - 1: việc sử dụng Forceupdate () không được khuyến khích và 2: cách này rất hữu ích cho các thành phần bên thứ 3 mà bạn đã cài đặt qua npm, nghĩa là không phải các thành phần của riêng bạn. Ví dụ: React-resizable-and-Movable là thành phần bên thứ 3 mà tôi sử dụng, nhưng nó không phản ứng với setstate thành phần của tôi. đây là giải pháp tuyệt vời
Varand Pezeshkian

80
Đây là một hack và lạm dụng key. Đầu tiên, ý định của nó không rõ ràng. Một người đọc mã của bạn sẽ phải làm việc chăm chỉ để hiểu lý do tại sao bạn sử dụng cách keynày. Thứ hai, điều này là không tinh khiết hơn forceUpdate. Phản ứng "thuần túy" có nghĩa là phần trình bày trực quan của thành phần của bạn phụ thuộc 100% vào trạng thái của nó, vì vậy nếu bạn thay đổi bất kỳ trạng thái nào, nó sẽ cập nhật. Tuy nhiên, nếu bạn có một số đối tượng lồng nhau sâu (kịch bản các forceUpdatetài liệu trích dẫn một lý do để sử dụng nó) thì việc sử dụng sẽ forceUpdatelàm cho nó rõ ràng. Thứ ba, Math.random()là ngẫu nhiên. Về mặt lý thuyết, nó có thể tạo ra cùng một số ngẫu nhiên.
nguyên tử

8
@xtraSimplicity Tôi không thể đồng ý rằng điều này tuân thủ cách làm của React. forceUpdatelà cách React để làm điều này.
Rob Grant

3
@Robert Grant, nhìn lại, tôi đồng ý. Sự phức tạp thêm vào không thực sự đáng giá.
XtraSimplility

80

Trên thực tế, forceUpdate()là giải pháp đúng duy nhất vì setState()có thể không kích hoạt kết xuất lại nếu logic bổ sung được triển khai trong shouldComponentUpdate()hoặc khi đơn giản trả về false.

ForceUpdate ()

Gọi forceUpdate()sẽ gây ra render()được gọi trên thành phần, bỏ qua shouldComponentUpdate(). hơn...

setState ()

setState()sẽ luôn kích hoạt kết xuất lại trừ khi logic kết xuất có điều kiện được triển khai trong shouldComponentUpdate(). hơn...


forceUpdate() có thể được gọi từ bên trong thành phần của bạn bởi this.forceUpdate()


Móc: Làm cách nào tôi có thể buộc thành phần kết xuất lại bằng móc trong React?


BTW: Bạn đang biến đổi trạng thái hoặc các thuộc tính lồng nhau của bạn không truyền bá?


1
một điều thú vị cần lưu ý là các xác nhận trạng thái bên ngoài setState như this.state.foo = 'bar' sẽ không kích hoạt phương thức vòng đời kết xuất
lfender6445

4
@ lfender6445 Gán trạng thái trực tiếp với this.statebên ngoài của hàm tạo cũng sẽ gây ra lỗi. Có thể đã không làm như vậy trong năm 2016; Nhưng, tôi khá chắc chắn rằng nó làm điều đó ngay bây giờ.
Tyler

Tôi đã thêm một số liên kết để làm việc xung quanh bài tập nhà nước trực tiếp.
Qwerty

36

Tôi đã tránh forceUpdatelàm theo

CÁCH SAU : không sử dụng chỉ mục làm khóa

this.state.rows.map((item, index) =>
   <MyComponent cell={item} key={index} />
)

CÁCH ĐÚNG : Sử dụng id dữ liệu làm khóa, nó có thể là một số hướng dẫn, v.v.

this.state.rows.map((item) =>
   <MyComponent item={item} key={item.id} />
)

Vì vậy, bằng cách thực hiện cải tiến mã như vậy, thành phần của bạn sẽ ĐỘC ĐÁO và hiển thị tự nhiên


this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
Tal

Cảm ơn bạn rất nhiều vì đã đưa tôi đi đúng hướng. Sử dụng chỉ số làm chìa khóa thực sự là vấn đề của tôi.
RoiEX

Để biện minh cho việc bỏ phiếu của tôi, mặc dù đó là một cách thực hành tốt để sử dụng phương pháp này, câu trả lời này không liên quan đến câu hỏi.
micnic

34

Khi bạn muốn hai thành phần React giao tiếp, không bị ràng buộc bởi mối quan hệ (cha-con), nên sử dụng Flux hoặc các kiến ​​trúc tương tự.

Những gì bạn muốn làm là lắng nghe những thay đổi của cửa hàng thành phần quan sát được , giữ mô hình và giao diện của nó, và lưu dữ liệu khiến kết xuất thay đổi như statetrong MyComponent. Khi cửa hàng đẩy dữ liệu mới, bạn thay đổi trạng thái của thành phần, tự động kích hoạt kết xuất.

Thông thường bạn nên cố gắng tránh sử dụng forceUpdate(). Từ tài liệu:

Thông thường, bạn nên cố gắng tránh tất cả các sử dụng của ForceUpdate () và chỉ đọc từ this.props và this.state trong render (). Điều này làm cho ứng dụng của bạn đơn giản và hiệu quả hơn nhiều


2
Trạng thái bộ nhớ của một trạng thái thành phần là gì? Nếu tôi có năm thành phần trên một trang và tất cả chúng đều đang nghe một cửa hàng, tôi có dữ liệu năm lần trong bộ nhớ hay chúng là tài liệu tham khảo? Và không phải tất cả những người nghe đó tăng lên nhanh chóng? Tại sao tốt hơn là "nhỏ giọt" hơn là chỉ truyền dữ liệu đến mục tiêu của bạn?
AJFarkas

5
Trên thực tế, các khuyến nghị là chuyển dữ liệu lưu trữ sang các đạo cụ thành phần và chỉ sử dụng trạng thái thành phần cho những thứ như trạng thái cuộn và các thứ cụ thể khác của ui. Nếu bạn sử dụng redux (tôi khuyên bạn nên sử dụng nó), bạn có thể sử dụng chức năng kết nối từ react-reduxđể tự động ánh xạ trạng thái lưu trữ thành các đạo cụ thành phần bất cứ khi nào cần dựa trên chức năng ánh xạ mà bạn cung cấp.
Stijn de Witt

1
@AJFarkas trạng thái sẽ được gán cho dữ liệu của một cửa hàng, dù sao nó cũng chỉ là một con trỏ cho nó để bộ nhớ không phải là vấn đề trừ khi bạn nhân bản.
Jason Sebring

4
"nên tránh ForceUpdate ()" là không chính xác. Tài liệu nói rõ: "Thông thường, bạn nên cố gắng tránh tất cả các sử dụng của ForceUpdate ()". Có các trường hợp sử dụng hợp lệ củaforceUpdate
AJP

2
@AJP bạn hoàn toàn đúng, đó là sự thiên vị cá nhân nói :) Tôi đã chỉnh sửa câu trả lời.
gcedo

18

sử dụng móc hoặc HOC chọn lựa của bạn

Sử dụng móc hoặc mẫu HOC (thành phần bậc cao hơn) , bạn có thể có các cập nhật tự động khi cửa hàng của bạn thay đổi. Đây là một cách tiếp cận rất nhẹ mà không có khung.

useStore Hook cách xử lý cập nhật cửa hàng

interface ISimpleStore {
  on: (ev: string, fn: () => void) => void;
  off: (ev: string, fn: () => void) => void;
}

export default function useStore<T extends ISimpleStore>(store: T) {
  const [storeState, setStoreState] = useState({store});
  useEffect(() => {
    const onChange = () => {
      setStoreState({store});
    }
    store.on('change', onChange);
    return () => {
      store.off('change', onChange);
    }
  }, []);
  return storeState.store;
}

withStores HOC xử lý cập nhật cửa hàng

export default function (...stores: SimpleStore[]) {
  return function (WrappedComponent: React.ComponentType<any>) {
    return class WithStore extends PureComponent<{}, {lastUpdated: number}> {
      constructor(props: React.ComponentProps<any>) {
        super(props);
        this.state = {
          lastUpdated: Date.now(),
        };
        this.stores = stores;
      }

      private stores?: SimpleStore[];

      private onChange = () => {
        this.setState({lastUpdated: Date.now()});
      };

      componentDidMount = () => {
        this.stores &&
          this.stores.forEach((store) => {
            // each store has a common change event to subscribe to
            store.on('change', this.onChange);
          });
      };

      componentWillUnmount = () => {
        this.stores &&
          this.stores.forEach((store) => {
            store.off('change', this.onChange);
          });
      };

      render() {
        return (
          <WrappedComponent
            lastUpdated={this.state.lastUpdated}
            {...this.props}
          />
        );
      }
    };
  };
}

Lớp học đơn giản

import AsyncStorage from '@react-native-community/async-storage';
import ee, {Emitter} from 'event-emitter';

interface SimpleStoreArgs {
  key?: string;
  defaultState?: {[key: string]: any};
}

export default class SimpleStore {
  constructor({key, defaultState}: SimpleStoreArgs) {
    if (key) {
      this.key = key;
      // hydrate here if you want w/ localState or AsyncStorage
    }
    if (defaultState) {
      this._state = {...defaultState, loaded: false};
    } else {
      this._state = {loaded: true};
    }
  }
  protected key: string = '';
  protected _state: {[key: string]: any} = {};
  protected eventEmitter: Emitter = ee({});
  public setState(newState: {[key: string]: any}) {
    this._state = {...this._state, ...newState};
    this.eventEmitter.emit('change');
    if (this.key) {
      // store on client w/ localState or AsyncStorage
    }
  }
  public get state() {
    return this._state;
  }
  public on(ev: string, fn:() => void) {
    this.eventEmitter.on(ev, fn);
  }
  public off(ev: string, fn:() => void) {
    this.eventEmitter.off(ev, fn);
  }
  public get loaded(): boolean {
    return !!this._state.loaded;
  }
}

Cách sử dụng

Trong trường hợp móc:

// use inside function like so
const someState = useStore(myStore);
someState.myProp = 'something';

Trong trường hợp của HOC:

// inside your code get/set your store and stuff just updates
const val = myStore.myProp;
myOtherStore.myProp = 'something';
// return your wrapped component like so
export default withStores(myStore)(MyComponent);

ĐẢM BẢO Để xuất các cửa hàng của bạn dưới dạng đơn lẻ để nhận được lợi ích của thay đổi toàn cầu như vậy:

class MyStore extends SimpleStore {
  public get someProp() {
    return this._state.someProp || '';
  }
  public set someProp(value: string) {
    this.setState({...this._state, someProp: value});
  }
}
// this is a singleton
const myStore = new MyStore();
export {myStore};

Cách tiếp cận này khá đơn giản và hiệu quả với tôi. Tôi cũng làm việc trong các nhóm lớn và sử dụng Redux và MobX và thấy những thứ đó cũng tốt nhưng chỉ là rất nhiều nồi hơi. Cá nhân tôi chỉ thích cách tiếp cận của riêng tôi bởi vì tôi luôn ghét rất nhiều mã cho một cái gì đó có thể đơn giản khi bạn cần nó.


2
Tôi nghĩ rằng có một lỗi đánh máy trong ví dụ về lớp Store của bạn trong phương thức cập nhật phải viết dòng đầu tiên của phương thức như sau : this._data = {...this._data, ...newData}.
Norbert

2
Phản ứng ngăn cản sự kế thừa có lợi cho thành phần. Reacjs.org/docs/compocation-vs-inherribution.html
Fred

1
Chỉ cần tự hỏi về sự rõ ràng / dễ đọc, làm thế nào coud this.setState (this.state) sẽ tốt hơn this.forceUpdate ()?
Zoman

17

Vì vậy, tôi đoán câu hỏi của tôi là: các thành phần React cần phải có trạng thái để đăng ký lại? Có cách nào để buộc thành phần cập nhật theo yêu cầu mà không thay đổi trạng thái không?

Các câu trả lời khác đã cố gắng minh họa cách bạn có thể, nhưng vấn đề là bạn không nên . Ngay cả các giải pháp hacky thay đổi chìa khóa cũng bỏ lỡ điểm. Sức mạnh của React là từ bỏ quyền kiểm soát quản lý thủ công khi có thứ gì đó sẽ hiển thị, và thay vào đó chỉ liên quan đến bản thân bạn về cách thứ gì đó nên ánh xạ vào đầu vào. Sau đó cung cấp dòng đầu vào.

Nếu bạn cần buộc kết xuất lại theo cách thủ công, bạn gần như chắc chắn không làm điều gì đó đúng.


@ art-solopov, bạn đang đề cập đến vấn đề gì? Những tài liệu nào trình bày chúng? Và giả sử bạn đang đề cập đến các đối tượng lồng nhau trong trạng thái, câu trả lời là sử dụng một cấu trúc khác để lưu trữ trạng thái của bạn. Đó rõ ràng là một cách xử lý trạng thái tối ưu phụ trong React. Bạn cũng không nên quản lý nhà nước một cách riêng biệt. Bạn đang mất một trong những lợi ích lớn nhất của React nếu bạn không làm việc với hệ thống quản lý nhà nước. Quản lý cập nhật thủ công là một mô hình chống.
Kyle Baker

Xin vui lòng, bạn có thể kiểm tra câu hỏi này stackoverflow.com/questions/61277292/ không?
HuLu ViCa

4

Bạn có thể làm điều đó một vài cách:

1. Sử dụng forceUpdate()phương pháp:

Có một số trục trặc có thể xảy ra khi sử dụng forceUpdate()phương pháp. Một ví dụ là nó bỏ qua shouldComponentUpdate()phương thức và sẽ hiển thị lại khung nhìn bất kể shouldComponentUpdate()trả về false. Do đó, nên tránh sử dụng ForceUpdate () khi có thể.

2. Truyền this.state cho setState()phương thức

Dòng mã sau khắc phục vấn đề với ví dụ trước:

this.setState(this.state);

Thực sự tất cả những gì đang làm là ghi đè trạng thái hiện tại bằng trạng thái hiện tại kích hoạt kết xuất lại. Đây vẫn chưa hẳn là cách tốt nhất để làm mọi thứ, nhưng nó đã khắc phục được một số trục trặc mà bạn có thể gặp phải khi sử dụng phương thức ForceUpdate ().


2
Vì setState được xử lý theo đợt nên có thể an toàn hơn để thực hiện:this.setState(prevState => prevState);
Mark Galloway

1
Không thực sự chắc chắn tại sao đó là một 'trục trặc'. Tên của phương thức ('forceUpdate') không thể rõ ràng hơn: buộc cập nhật luôn.
Zoman

4

Có một số cách để đăng ký lại thành phần của bạn:

Giải pháp đơn giản nhất là sử dụng phương thức ForceUpdate ():

this.forceUpdate()

Một giải pháp nữa là tạo khóa không được sử dụng ở trạng thái (nonUsedKey) và gọi hàm setState với bản cập nhật của nonUsedKey này:

this.setState({ nonUsedKey: Date.now() } );

Hoặc viết lại tất cả trạng thái hiện tại:

this.setState(this.state);

Đạo cụ thay đổi cũng cung cấp rerender thành phần.


3

Để hoàn thiện, bạn cũng có thể đạt được điều này trong các thành phần chức năng:

const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
// ...
forceUpdate();

Hoặc, như một cái móc tái sử dụng:

const useForceUpdate = () => {
  const [, updateState] = useState();
  return useCallback(() => updateState({}), []);
}
// const forceUpdate = useForceUpdate();

Xem: https://stackoverflow.com/a/53215514/2692307

Xin lưu ý rằng việc sử dụng một cơ chế cập nhật lực lượng vẫn là một thực tiễn tồi vì nó đi ngược lại với tâm lý phản ứng, vì vậy vẫn nên tránh nếu có thể.


2

Chúng ta có thể sử dụng this.forceUpdate () như dưới đây.

       class MyComponent extends React.Component {



      handleButtonClick = ()=>{
          this.forceUpdate();
     }


 render() {

   return (
     <div>
      {Math.random()}
        <button  onClick={this.handleButtonClick}>
        Click me
        </button>
     </div>
    )
  }
}

 ReactDOM.render(<MyComponent /> , mountNode);

Phần Element 'Math.random' trong DOM chỉ được cập nhật ngay cả khi bạn sử dụng setState để kết xuất lại thành phần.

Tất cả các câu trả lời ở đây là bổ sung chính xác cho câu hỏi để hiểu..như chúng tôi biết để kết xuất lại một thành phần mà không sử dụng setState ({}) bằng cách sử dụng ForceUpdate ().

Đoạn mã trên chạy với setState như bên dưới.

 class MyComponent extends React.Component {



             handleButtonClick = ()=>{
                this.setState({ });
              }


        render() {
         return (
  <div>
    {Math.random()}
    <button  onClick={this.handleButtonClick}>
      Click me
    </button>
  </div>
)
  }
 }

ReactDOM.render(<MyComponent /> , mountNode);

1

Chỉ cần một câu trả lời khác để sao lưu câu trả lời được chấp nhận :-)

React không khuyến khích việc sử dụng forceUpdate()bởi vì họ thường có cách tiếp cận rất "đây là cách duy nhất để thực hiện" đối với lập trình chức năng. Điều này tốt trong nhiều trường hợp, nhưng nhiều nhà phát triển React đi kèm với nền OO và với cách tiếp cận đó, việc nghe một đối tượng quan sát được là hoàn toàn ổn.

Và nếu bạn làm như vậy, có lẽ bạn biết bạn PHẢI kết xuất lại khi "đám cháy" có thể quan sát được, và như vậy, bạn NÊN sử dụng forceUpdate()và đó thực sự là một điểm cộng shouldComponentUpdate()KHÔNG liên quan ở đây.

Các công cụ như MobX, sử dụng phương pháp OO, thực sự đang thực hiện việc này bên dưới bề mặt (thực tế là các cuộc gọi MobX render()trực tiếp)


0

Tôi đã tìm thấy nó tốt nhất để tránh ForceUpdate (). Một cách để buộc kết xuất lại là thêm phụ thuộc của render () vào một biến ngoài tạm thời và thay đổi giá trị của biến đó khi cần.

Đây là một ví dụ mã:

class Example extends Component{
   constructor(props){
      this.state = {temp:0};

      this.forceChange = this.forceChange.bind(this);
   }

   forceChange(){
      this.setState(prevState => ({
          temp: prevState.temp++
      })); 
   }

   render(){
      return(
         <div>{this.state.temp &&
             <div>
                  ... add code here ...
             </div>}
         </div>
      )
   }
}

Gọi this.forceChange () khi bạn cần buộc kết xuất lại.


0

ES6 - Tôi bao gồm một ví dụ, rất hữu ích cho tôi:

Trong "câu lệnh if ngắn", bạn có thể truyền hàm rỗng như thế này:

isReady ? ()=>{} : onClick

Đây dường như là cách tiếp cận ngắn nhất.

()=>{}


0

Để thực hiện những gì bạn đang mô tả, vui lòng thử cái này.forceUpdate ().


Hành động này làm gì?
Dominique

0

Một cách khác đang kêu gọi setState, duy trì trạng thái:

this.setState(prevState=>({...prevState}));


0

ForceUpdate (), nhưng mỗi khi tôi nghe ai đó nói về nó, bạn sẽ không bao giờ sử dụng nó.


-1

Bạn có thể sử dụng ForceUpdate () để kiểm tra chi tiết hơn ( forceUpdate () ).


1
Vì tò mò, tại sao lại để câu trả lời này nếu trong 4 năm mọi người đã đưa ra rằng đó là một giải pháp khả thi trong chủ đề này?
Byron Coetsee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.