Supposons que nous ayons le code suivant:
const [obj, setobj] = useState(generateInitialObj());
Pourquoi se produit-il que generateInitialObj () soit appelé deux fois? J'ai ajouté la journalisation à generateInitialObj () et je viens de le remarquer. Cela semble se produire au tout début du cycle de vie du composant. Je pense qu'une fois que react obtient une valeur à partir de là, ça va y rester pour de bon. Pas besoin de le réobtenir. Des idées?
3 Réponses :
C'est une technicité JavaScript. Il n'y a rien que React puisse faire pour empêcher generateInitialObj d'être appelé sur chaque rendu. Pour en tenir compte, React prend en charge l'API suivante à la place:
const [obj, setobj] = useState(() => generateInitialObj());
Je pense que le re-rendu du composant est la raison derrière cela. pouvez-vous s'il vous plaît publier la hiérarchie des composants?
Essayez également ceci:
const [obj, setobj] = useState(() => generateInitialObj());
voici un exemple fonctionnel: https://stackblitz.com/edit/react-mysrjp
p >
Je viens de tester et de confirmer que si vous utilisez un appel de fonction getInitialState () , il sera appelé à chaque fois, car il s'agit bien d'un comportement JS normal.
<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"/>
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'));
Mais si vous utilisez une déclaration de fonction () => getInitialState () à la place, elle ne sera appelée qu'une seule fois.
<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"/>
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'));
À part cela, les deux fonctionnent exactement de la même manière.
Vous avez probablement un composant parent dont l'état est mis à jour et ré-rendu. Par conséquent, re-rendre votre composant enfant.