Tôi có một thành phần chức năng và tôi muốn buộc nó hiển thị lại.
Làm thế nào tôi có thể làm như vậy?
Vì không có phiên bản nào this
nên tôi không thể gọi this.forceUpdate()
.
Tôi có một thành phần chức năng và tôi muốn buộc nó hiển thị lại.
Làm thế nào tôi có thể làm như vậy?
Vì không có phiên bản nào this
nên tôi không thể gọi this.forceUpdate()
.
Câu trả lời:
Sử dụng các móc phản ứng, bây giờ bạn có thể gọi useState()
trong thành phần hàm của mình.
useState()
sẽ trả về một mảng gồm 2 thứ:
1. Một giá trị, đại diện cho trạng thái hiện tại.
2. Bộ định vị của nó. Sử dụng nó để cập nhật giá trị.
Việc cập nhật giá trị bằng trình thiết lập của nó sẽ buộc thành phần hàm của bạn hiển thị lại ,
giống như forceUpdate
:
import React, { useState } from 'react';
//create your forceUpdate hook
function useForceUpdate(){
const [value, setValue] = useState(0); // integer state
return () => setValue(value => ++value); // update the state to force render
}
function MyComponent() {
// call your hook here
const forceUpdate = useForceUpdate();
return (
<div>
{/*Clicking on the button will force to re-render like force update does */}
<button onClick={forceUpdate}>
Click to re-render
</button>
</div>
);
}
Bạn có thể tìm thấy một bản demo ở đây .
Thành phần trên sử dụng một hàm hook tùy chỉnh ( useForceUpdate
) sử dụng một hook trạng thái boolean ( useState
). Nó chuyển đổi trạng thái boolean và do đó yêu cầu React chạy lại chức năng kết xuất.
Trong phiên bản cũ của câu trả lời này, đoạn mã đã sử dụng giá trị boolean và chuyển nó vào forceUpdate()
. Bây giờ tôi đã chỉnh sửa câu trả lời của mình, đoạn mã sử dụng một số thay vì boolean.
Tại sao ? (bạn sẽ hỏi tôi)
Bởi vì một lần nó xảy ra với tôi rằng my forceUpdate()
đã được gọi hai lần sau đó từ 2 sự kiện khác nhau, và do đó nó đang gửi lại giá trị boolean ở trạng thái ban đầu và thành phần không bao giờ được hiển thị.
Bởi vì trong useState
setter của '( setValue
ở đây), hãy React
so sánh trạng thái trước đó với trạng thái mới và chỉ hiển thị nếu trạng thái khác.
forceUpdate
.
useState
hook, chứ không phải class ' setState
thực sự không tạo ra một so sánh (trừ khi bạn triển khai phương thức shouldUpdate). Xem các bản demo cùng tôi được đăng, nhưng với một giá trị tĩnh sử dụng cho setState
, nó không làm nữa: codesandbox.io/s/determined-rubin-8598l
Cập nhật react v16.8 (bán lại vào ngày 16 tháng 2 năm 2019)
Kể từ khi phản ứng 16.8 được phát hành với hook , các thành phần chức năng giờ đây có khả năng giữ lâu dài state
. Với khả năng mà bạn có thể bây giờ bắt chước một forceUpdate
:
Lưu ý rằng phương pháp này nên được xem xét lại và trong hầu hết các trường hợp khi bạn cần cập nhật, có thể bạn đã làm sai.
Trước khi phản ứng 16.8.0
Không, bạn không thể, các thành phần chức năng State-Less chỉ bình thường functions
trả về jsx
, bạn không có bất kỳ quyền truy cập nào vào các phương thức vòng đời React vì bạn không mở rộng từ React.Component
.
Hãy nghĩ về hàm-thành phần như render
một phần phương thức của các thành phần lớp.
props
hoặc mới state
. bạn không thể bắt buộc chức năng kết xuất vì không có render
chức năng nào trên các thành phần không trạng thái. các thành phần không trạng thái không phải extends
React.Component
chúng chỉ là các hàm đơn giản trả về jsx
.
Câu hỏi thường gặp chính thức ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate ) hiện khuyến nghị cách này nếu bạn thực sự cần làm điều đó:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
const [, forceUpdate] = useReducer(x => x + 1, 0);
Tôi đã sử dụng thư viện của bên thứ ba có tên là use-force-update để buộc hiển thị các thành phần chức năng phản ứng của mình. Làm việc như một sự quyến rũ. Chỉ cần sử dụng nhập gói trong dự án của bạn và sử dụng như thế này.
import useForceUpdate from 'use-force-update';
const MyButton = () => {
const forceUpdate = useForceUpdate();
const handleClick = () => {
alert('I will re-render now.');
forceUpdate();
};
return <button onClick={handleClick} />;
};
useForceUpdate
sử dụng useCallback
như đã đề cập trong các câu trả lời khác. Lib này chỉ là một lib tiện ích giúp bạn tiết kiệm một vài lần gõ phím.
Tuyên bố từ chối trách nhiệm: KHÔNG PHẢI TRẢ LỜI CHO VẤN ĐỀ.
Để lại một ghi chú quan trọng ở đây:
Nếu bạn đang cố gắng cập nhật một thành phần không trạng thái, rất có thể thiết kế của bạn đã xảy ra lỗi.
Hãy xem xét các trường hợp sau:
Điều này có thể được thực hiện mà không cần sử dụng hook rõ ràng với điều kiện bạn thêm một chỗ dựa vào thành phần của mình và một trạng thái vào thành phần mẹ của thành phần không trạng thái:
const ParentComponent = props => {
const [updateNow, setUpdateNow] = useState(true)
const updateFunc = () => {
setUpdateNow(!updateNow)
}
const MyComponent = props => {
return (<div> .... </div>)
}
const MyButtonComponent = props => {
return (<div> <input type="button" onClick={props.updateFunc} />.... </div>)
}
return (
<div>
<MyComponent updateMe={updateNow} />
<MyButtonComponent updateFunc={updateFunc}/>
</div>
)
}
Câu trả lời được chấp nhận là tốt. Chỉ để làm cho nó dễ hiểu hơn.
Thành phần ví dụ:
export default function MyComponent(props) {
const [updateView, setUpdateView] = useState(0);
return (
<>
<span style={{ display: "none" }}>{updateView}</span>
</>
);
}
Để buộc kết xuất, hãy gọi mã bên dưới:
setUpdateView((updateView) => ++updateView);