javascript React:如何在组件的生命周期中只调用一次方法,只要 data.loading 为 false
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51104316/
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 call a method only once in the lifecycle of a component, as soon as data.loading is false
提问by Alina Boghiu
I have a React component with a prop 'total' that changes every time the component is updated:
我有一个带有属性“total”的 React 组件,每次更新组件时都会更改:
function MyView(props) {
const total = props.data.loading ? 0 : props.data.total;
return (
<p> total </p>
);
}
The first time the component mounts the total is say 10. Every time the component is updated because of a prop change the total goes up.
组件第一次挂载总数为 10。每次组件因 prop 更改而更新时,总数都会增加。
Is there a way I can display the original total (in this example 10)?
有没有办法可以显示原始总数(在本例中为 10)?
I have tried setting it in this.total inside componentDidMount, but props.data.total is not yet available when componentDidMount is called. Same with the constructor. The total only becomes available when props.data.loading is false.
我尝试在 componentDidMount 内的 this.total 中设置它,但是在调用 componentDidMount 时 props.data.total 尚不可用。与构造函数相同。只有当 props.data.loading 为 false 时,总数才可用。
回答by Tholle
You could create a stateful component and store the initial totalin the component state.
您可以创建一个有状态组件并将初始值存储total在组件状态中。
Example
例子
class MyView extends React.Component {
state = {
initialTotal: this.props.total
};
render() {
const { total } = this.props;
const { initialTotal } = this.state;
return (
<div>
<p> Total: {total} </p>
<p> Initial total: {initialTotal} </p>
</div>
);
}
}
class App extends React.Component {
state = {
total: 10
};
componentDidMount() {
this.interval = setInterval(() => {
this.setState(({ total }) => {
return { total: total + 1 };
});
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <MyView total={this.state.total} />;
}
}
回答by LiranC
In order to get access to lifecycle features, you must move from function, stateless component, to a class component.
为了访问生命周期功能,您必须从功能、无状态组件移动到类组件。
in the below example, InitialTotalis initialized in the construstorlifecycle method and it never changes.
在下面的示例中,InitialTotal在construstor生命周期方法中初始化并且它永远不会改变。
currentTotal, is incremented each time the render function is called - when the component is re-rendered (because of props change or state changes)
currentTotal, 每次调用渲染函数时都会增加 - 重新渲染组件时(因为道具更改或状态更改)
it should look something like that:
它应该看起来像这样:
class MyView extends React.Component {
constructor(props) {
super(props)
this.initialTotal = 10;
this.currentTotal = 10;
}
render() {
this.currentTotal+=1;
return (
<p>InitialToal: {this.initialTotal}</p>
<p>Current Total: {this.currentTotal}</p>
);
}
}
回答by user1768699
If I understand your requirements correctly...
如果我正确理解您的要求...
function MyView(props) {
// if you only need to set the value once on load just use useState.
// the const total will be the value you pass in to useState.
const [total, setTotal] = useState(props.data.loading ? 0 : props.data.total)
// if its possible that the value is not available on initial load and
// you want to set it only once, when it becomes available, you can use
// useEffect with useState
useEffect(() => {
// some condition to know if data is ready to set
if (!props.data.loading) {
setTotal(props.data.total)
}
}, [props.data.total, setTotal, props.data.loading]
// this array allows you to limit useEffect to only be called when
// one of these values change. ( when total changes in this case,
// as the const function setTotal will not change
// ( but react will fuss if its used and not in the list ).
return (
<p> {total} </p>
);
}
回答by RIYAJ KHAN
You can use getDerivedStateFromPropslife cycle method.
您可以使用getDerivedStateFromProps生命周期方法。
static getDerivedStateFromProps(props, state){
if(props.data.total && (props.data.total==10)){
return {
total : props.total // show total only when its 10
}
}else{
return null; // does not update state
}
}

