我有一个函数组件,我想强制它重新渲染。
我该怎么做呢? 因为没有实例this,所以我不能调用this. forceupdate()。
我有一个函数组件,我想强制它重新渲染。
我该怎么做呢? 因为没有实例this,所以我不能调用this. forceupdate()。
当前回答
对我来说,仅仅更新状态是行不通的。我正在使用带有组件的库,看起来我不能强制组件更新。
我的方法是用条件渲染扩展上面的方法。在我的例子中,我想在值改变时调整组件的大小。
//hook to force updating the component on specific change
const useUpdateOnChange = (change: unknown): boolean => {
const [update, setUpdate] = useState(false);
useEffect(() => {
setUpdate(!update);
}, [change]);
useEffect(() => {
if (!update) setUpdate(true);
}, [update]);
return update;
};
const MyComponent = () => {
const [myState, setMyState] = useState();
const update = useUpdateOnChange(myState);
...
return (
<div>
... ...
{update && <LibraryComponent />}
</div>
);
};
您需要传递想要跟踪更改的值。钩子返回用于条件呈现的布尔值。
当更改值触发时,useEffect更新将变为false,从而隐藏组件。在此之后,第二个useEffect被触发,update变为true,这使得组件再次可见,并导致更新(在我的例子中是调整大小)。
其他回答
更新react v16.8(2019年2月16日发布)
由于react 16.8发布了钩子,函数组件有能力保持持久状态。有了这个能力,你现在可以模仿一个forceUpdate:
function App() { const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []); console.log("render"); return ( <div> <button onClick={forceUpdate}>Force Render</button> </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script> <div id="root"/>
请注意,这种方法应该重新考虑,在大多数情况下,当您需要强制更新时,您可能会做错一些事情。
react 16.8.0之前
不,你不能,无状态函数组件只是返回jsx的普通函数,你没有任何访问React生命周期方法的权限,因为你没有从React. component扩展。
可以将function-component看作类组件的呈现方法部分。
如果您正在使用版本< 16.8的功能组件。一种解决方法是直接调用相同的函数
import React from 'react';
function MyComponent() {
const forceUpdate = MyComponent();
return (
<div>
<button onClick={forceUpdate}>
Click to re-render
</button>
</div>
);
}
但如果你给它一些支撑,它就会断裂。在我的情况下,我只是通过相同的道具,我收到了渲染功能。
我使用了一个第三方库 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} />;
};
这可以在不显式使用钩子的情况下完成,只要你给你的组件添加一个道具,给无状态组件的父组件添加一个状态:
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>
)
}
对我来说,仅仅更新状态是行不通的。我正在使用带有组件的库,看起来我不能强制组件更新。
我的方法是用条件渲染扩展上面的方法。在我的例子中,我想在值改变时调整组件的大小。
//hook to force updating the component on specific change
const useUpdateOnChange = (change: unknown): boolean => {
const [update, setUpdate] = useState(false);
useEffect(() => {
setUpdate(!update);
}, [change]);
useEffect(() => {
if (!update) setUpdate(true);
}, [update]);
return update;
};
const MyComponent = () => {
const [myState, setMyState] = useState();
const update = useUpdateOnChange(myState);
...
return (
<div>
... ...
{update && <LibraryComponent />}
</div>
);
};
您需要传递想要跟踪更改的值。钩子返回用于条件呈现的布尔值。
当更改值触发时,useEffect更新将变为false,从而隐藏组件。在此之后,第二个useEffect被触发,update变为true,这使得组件再次可见,并导致更新(在我的例子中是调整大小)。