说我们有以下代码:
const [obj, setobj] = useState(generateInitialObj());
为什么发生generateInitialObj()被调用两次的情况?我已经将日志记录添加到generateInitialObj()中,我刚刚注意到了它。它似乎发生在组件生命周期的最开始。但是,一旦有反应从那里获得价值,我就会永远留在那里。无需重新获取它。 有什么想法吗?
答案 0 :(得分:2)
这是JavaScript技术。 React无法阻止每个单独的渲染调用var receta = this.BindingContext;
。为了解决这个问题,React改为支持以下API:
generateInitialObj
答案 1 :(得分:0)
我认为组件的re-rendering
是其背后的原因。您可以发布组件层次结构吗?
也可以尝试以下方法:
const [obj, setobj] = useState(() => generateInitialObj());
这是一个工作示例: https://stackblitz.com/edit/react-mysrjp
答案 2 :(得分:0)
经过测试并确认,如果您使用函数调用getInitialState()
,那么它将每次都被调用,因为它确实是正常的JS行为。
function getInitialState() {
console.log('Executing getInitialState...');
return({
propA: 'foo',
propB: 'bar'
});
}
function App() {
console.log('Rendering App...');
const [myState,setMyState] = React.useState(getInitialState());
const [myBoolean,setMyBoolean] = React.useState(false);
function updateApp() {
setMyBoolean((prevState) => !prevState);
}
function changeAppState() {
setMyState({
propA: 'foo2',
propB: 'bar2'
});
}
return(
<React.Fragment>
<div>myState.propA: {myState.propA}</div>
<div>myState.propB: {myState.propB}</div>
<button onClick={updateApp}>Update App</button>
<button onClick={changeAppState}>Change App State</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
但是,如果您改用函数声明()=>getInitialState()
,则它将仅被调用一次。
function getInitialState() {
console.log('Executing getInitialState...');
return({
propA: 'foo',
propB: 'bar'
});
}
function App() {
console.log('Rendering App...');
const [myState,setMyState] = React.useState(()=>getInitialState());
const [myBoolean,setMyBoolean] = React.useState(false);
function updateApp() {
setMyBoolean((prevState) => !prevState);
}
function changeAppState() {
setMyState({
propA: 'foo2',
propB: 'bar2'
});
}
return(
<React.Fragment>
<div>myState.propA: {myState.propA}</div>
<div>myState.propB: {myState.propB}</div>
<button onClick={updateApp}>Update App</button>
<button onClick={changeAppState}>Change App State</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
除此之外,两者的工作原理相同。