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.