Javascript React - 如何强制渲染函数组件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46240647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React - How can I force render a function component?
提问by Gorakh Nath
I have a function component, and I want to re-render it. How can I do so? Since there's no instance this, I cannot call this.forceUpdate().
我有一个函数组件,我想重新渲染它。我怎么能这样做?由于没有实例this,我无法调用this.forceUpdate().
How can I force render my component ?
如何强制渲染我的组件?
回答by Yairopro
You can now, using React hooks
你现在可以使用React 钩子
Using react hooks, you can now call useState()in your component function. This will return an array of 2 things: a value, and a "setter" function you can use to update the first value returned, and doing so, it will force your function component to re-render, just like forceUpdatedoes:
使用 react 钩子,您现在可以调用useState()组件函数。这将返回一个包含两件事的数组:一个值和一个“setter”函数,您可以使用它来更新返回的第一个值,这样做会强制您的函数组件重新渲染,就像这样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() {
// use your hook her
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>
);
}
The component above uses a custom hook function (useForceUpdate) which uses a boolean state hook (useState). It toggles the boolean state and thus tells React to re-run the render function.
上面的组件使用自定义钩子函数 ( useForceUpdate),它使用布尔状态钩子 ( useState)。它切换布尔状态,从而告诉 React 重新运行渲染函数。
EDIT
编辑
In a old version of this answer, the snippet used a boolean value, and toggled it in forceUpdate(). Now I've edited my answer, and the snippet use a number rather than a boolean. Why (you would ask me) ? Because it happened to me that the forceUpdate()was called 2 times subsequently from 2 different events, which reset the value at its original state, and it didn't render. Because in useState's setter, Reactcompare the previous state with the new one, and render only if the state is different.
在此答案的旧版本中,该代码段使用了一个布尔值,并在forceUpdate(). 现在我已经编辑了我的答案,并且代码片段使用了数字而不是布尔值。为什么(你会问我)?因为我碰巧forceUpdate()随后从 2 个不同的事件中调用了 2 次,这些事件将值重置为其原始状态,并且没有呈现。因为 inuseState的 setterReact将之前的状态与新的状态进行比较,只有状态不同时才渲染。
回答by Sagiv b.g
Update react v16.8 (16 Feb 2019 realease)
更新 react v16.8(2019 年 2 月 16 日发布)
Since react 16.8 released with hooks, function components are now have the ability to hold persistent state. With that ability you can now mimica forceUpdate:
自从react 16.8 发布了带有钩子的东西,函数组件现在可以保持持久化state。有了这种能力,你现在可以模仿一个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"/>
Note that this approach should be re-considered and in most caseswhen you need to force an update you probably doing something wrong.
请注意,应该重新考虑这种方法,并且在大多数情况下,当您需要强制更新时,您可能做错了什么。
Before react 16.8.0
反应前 16.8.0
No you can't, State-Less function components are just normal functionsthat returns jsx, you don't have any access to the React life cycle methods as you are not extending from the React.Component.
不,你不能,无状态函数组件只是正常的functions返回jsx,你没有任何访问 React 生命周期方法的权限,因为你没有从React.Component.
Think of function-component as the rendermethod part of the class components.
将函数组件视为render类组件的方法部分。
回答by Charith Jayasanka
I used a third party library called use-force-updateto force render my react functional components. Worked like charm. Just use import the package in your project and use like this.
我使用了一个名为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} />;
};
回答by Gramotei
Official FAQ ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate) now recommends this way if you reallyneed to do it:
如果您确实需要这样做,官方常见问题解答(https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate)现在推荐这种方式:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
回答by Ankan-Zerob
Disclaimer: NOT AN ANSWER TO THE PROBLEM.
免责声明:不是问题的答案。
Leaving an Important note here:
在此留下重要说明:
If you are trying to forceupdate a stateless component, chances are there is something wrong with your design.
如果您尝试强制更新无状态组件,则您的设计可能有问题。
Consider the following cases:
考虑以下情况:
- Pass a setter (setState) to a child component that can change state and cause the parent component to re-render.
- Consider lifting state up
- Consider putting that state in your Redux store, that can automatically force a re-render on connected components.
- 将 setter (setState) 传递给可以更改状态并导致父组件重新渲染的子组件。
- 考虑提升状态
- 考虑将该状态放在您的 Redux 存储中,它可以自动强制重新渲染连接的组件。
回答by Manohar Reddy Poreddy
Accepted answer is good.
接受的答案很好。
Just making it simpler to understand & easy to copy paste, to save sometime.
只是让它更容易理解和易于复制粘贴,以节省一些时间。
Example component:
示例组件:
export default function MyComponent(props) {
const [udpateView, setUdpateView] = useState(0);
return (
<>
<span style={{ display: "none" }}>{udpateView}</span>
</>
);
}
To render the component, call the below code, anywhere inside the component:
要渲染组件,请在组件内的任何位置调用以下代码:
setUdpateView((udpateView) => ++udpateView);
回答by Charles Goodwin
This can be done without explicitly using hooks provided you add a prop to your component and a state to the stateless component's parent component:
如果您向组件添加 prop 并向无状态组件的父组件添加状态,则无需显式使用钩子即可完成此操作:
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>
)
}

