我有一个函数组件,我想强制它重新渲染。
我该怎么做呢? 因为没有实例this,所以我不能调用this. forceupdate()。
我有一个函数组件,我想强制它重新渲染。
我该怎么做呢? 因为没有实例this,所以我不能调用this. forceupdate()。
当前回答
官方常见问题现在推荐这种方式,如果你真的需要这样做:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
其他回答
官方常见问题现在推荐这种方式,如果你真的需要这样做:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
我使用了一个第三方库 use-force-update 强制渲染我的react功能组件。工作很有魅力。 只需在项目中使用import包并像这样使用。
import useForceUpdate from 'use-force-update';
const MyButton = () => {
const forceUpdate = useForceUpdate();
const handleClick = () => {
alert('I will re-render now.');
forceUpdate();
};
return <button onClick={handleClick} />;
};
这些都没有给我一个满意的答案,所以最后我得到了我想要的关键道具,useRef和一些随机id生成器,如shortid。
基本上,我想要一些聊天应用在别人第一次打开应用时发挥自己的作用。所以,我需要完全控制什么时候和什么答案更新与异步等待的易用性。
示例代码:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// ... your JSX functional component, import shortid somewhere
const [render, rerender] = useState(shortid.generate())
const messageList = useRef([
new Message({id: 1, message: "Hi, let's get started!"})
])
useEffect(()=>{
async function _ () {
await sleep(500)
messageList.current.push(new Message({id: 1, message: "What's your name?"}))
// ... more stuff
// now trigger the update
rerender(shortid.generate())
}
_()
}, [])
// only the component with the right render key will update itself, the others will stay as is and won't rerender.
return <div key={render}>{messageList.current}</div>
事实上,这也允许我滚动一些像聊天信息滚动。
const waitChat = async (ms) => {
let text = "."
for (let i = 0; i < ms; i += 200) {
if (messageList.current[messageList.current.length - 1].id === 100) {
messageList.current = messageList.current.filter(({id}) => id !== 100)
}
messageList.current.push(new Message({
id: 100,
message: text
}))
if (text.length === 3) {
text = "."
} else {
text += "."
}
rerender(shortid.generate())
await sleep(200)
}
if (messageList.current[messageList.current.length - 1].id === 100) {
messageList.current = messageList.current.filter(({id}) => id !== 100)
}
}
如果你已经在函数组件中有一个状态,而你不想改变它并需要重新呈现,你可以伪造一个状态更新,这将反过来重新呈现组件
const [items,setItems] = useState({
name:'Your Name',
status: 'Idle'
})
const reRender = () =>{
setItems((state) => [...state])
}
这将保持状态不变,并将做出反应,认为状态已更新
最佳方法-没有多余的变量重新创建在每次渲染:
const forceUpdateReducer = (i) => i + 1
export const useForceUpdate = () => {
const [, forceUpdate] = useReducer(forceUpdateReducer, 0)
return forceUpdate
}
用法:
const forceUpdate = useForceUpdate()
forceUpdate()