I have got a trouble with updating an object inside React component with events.
const Comp = (props) => {
...
let tango = {alpha: null};
...
let handleFirst = () => {
tango.alpha = "CLICK";
console.log(tango);
}
let handleSecond = () => {
console.log(tango);
}
return (
<div id="first" onClick={handleFirst}>text</div>
<div id="second" onClick={handleSecond}>image</div>
)
}
When I click on div first
I receive the following console output: {alpha: "CLICK"}
, but when I click on div second
I receive console output as it is null: {alpha: null}
. I don't want to include tango
into useState
function because I want to update state of the component after another trigger, so I don't need to render component after each edit of object.
It seems to me very discouragingly but I don't know what to I've tried almost everything, and it seems to me to add alpha
to state will be solution but I hope I can avoid it.
CodePudding user response:
It sounds like there's some some re-rendering in between the first click on the second - if there wasn't, the tango
closed over by the handleFirst
that gets invoked would be the same one closed over by the invoked handleSecond
:
const Comp = (props) => {
let tango = {alpha: null};
let handleFirst = () => {
tango.alpha = "CLICK";
console.log(tango);
}
let handleSecond = () => {
console.log(tango);
}
return (<div>
<div id="first" onClick={handleFirst}>text</div>
<div id="second" onClick={handleSecond}>image</div>
</div>)
}
ReactDOM.render(<Comp />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If you want to keep a persistent reference to tango
across re-renders, without the change to it causing a re-render itself, you can use a ref instead:
const Comp = (props) => {
let tangoRef = React.useRef({alpha: null});
const [someState, setSomeState] = React.useState(0);
let handleFirst = () => {
tangoRef.current.alpha = "CLICK";
setSomeState(someState 1);
console.log(tangoRef.current);
}
let handleSecond = () => {
console.log(tangoRef.current);
}
return (<div>
<div id="first" onClick={handleFirst}>text</div>
<div id="second" onClick={handleSecond}>image</div>
</div>)
}
ReactDOM.render(<Comp />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>