I want to be able to change a value from both inside and outside a component.
Below is a copy of my attempt, from
The problem is self documented in the sandbox, here is a copy:
- Change from the ouside works if done before change from the inside
- Once changed from the inside, impossible to change again from the outside
App.js file:
import React, { useState } from "react";
import "./styles.css";
import TestParam from "./TestParam";
export default function App() {
const [outsideChange, setOutsideChange] = useState(null);
return (
<div className="App">
<button
onClick={() => {
setOutsideChange("");
setOutsideChange("Changed from outside");
}}
>
Change from the outside
</button>
<br />
<br />
<TestParam testStringProp={outsideChange} />
</div>
);
}
TestParam.js file:
import React, { useState, useEffect } from "react";
export default function TestParam({ testStringProp }) {
const [testString, setTestString] = useState(testStringProp);
useEffect(() => {
setTestString(testStringProp);
// alert("in useEffect");
}, [testStringProp]);
return (
<>
<button onClick={() => setTestString("changed from inside component")}>
Change from inside
</button>
<h1>Result here: {testString}</h1>
<p>Change from the ouside works if done before change from the inside</p>
<p>
Once changed from the inside, impossible to change again from the
outside
</p>
</>
);
}
I want to be able to change a value from both inside and outside a component.
Below is a copy of my attempt, from https://codesandbox.io/p/sandbox/42xrs2
The problem is self documented in the sandbox, here is a copy:
- Change from the ouside works if done before change from the inside
- Once changed from the inside, impossible to change again from the outside
App.js file:
import React, { useState } from "react";
import "./styles.css";
import TestParam from "./TestParam";
export default function App() {
const [outsideChange, setOutsideChange] = useState(null);
return (
<div className="App">
<button
onClick={() => {
setOutsideChange("");
setOutsideChange("Changed from outside");
}}
>
Change from the outside
</button>
<br />
<br />
<TestParam testStringProp={outsideChange} />
</div>
);
}
TestParam.js file:
import React, { useState, useEffect } from "react";
export default function TestParam({ testStringProp }) {
const [testString, setTestString] = useState(testStringProp);
useEffect(() => {
setTestString(testStringProp);
// alert("in useEffect");
}, [testStringProp]);
return (
<>
<button onClick={() => setTestString("changed from inside component")}>
Change from inside
</button>
<h1>Result here: {testString}</h1>
<p>Change from the ouside works if done before change from the inside</p>
<p>
Once changed from the inside, impossible to change again from the
outside
</p>
</>
);
}
Share
Improve this question
edited Nov 20, 2024 at 11:21
DarkBee
15.6k8 gold badges72 silver badges117 bronze badges
asked Nov 20, 2024 at 11:19
FrancisFrancis
8571 gold badge9 silver badges21 bronze badges
1 Answer
Reset to default 1The outside state doesn't actually change because React batches state updates by defaults. When you call
setOutsideChange("");
setOutsideChange("Changed from outside");
the updates are combined, which means that the state isn't cleared and then updated, and see the current and previous states are identical, the value of testStringProp
doesn't actually change, and the useEffect
is not triggered.
A simple solution would be to change the value you set. For example, replace setOutsideChange("Changed from outside")
with setOutsideChange(Math.random())
, and you should see it's updating.
If you need static text, you'll need to wrap each set state with flushSync
, so each of them would cause a re-render, first clearing the state, and then setting the text.
const { useState, useEffect } = React;
const { flushSync, createRoot } = ReactDOM;
function App() {
const [outsideChange, setOutsideChange] = useState(null);
return (
<div className="App">
<button
onClick={() => {
flushSync(() => setOutsideChange(""));
flushSync(() => setOutsideChange("Changed from outside"));
}}
>
Change from the outside
</button>
<br />
<br />
<TestParam testStringProp={outsideChange} />
</div>
);
}
function TestParam({ testStringProp }) {
const [testString, setTestString] = useState(testStringProp);
useEffect(() => {
setTestString(testStringProp);
// alert("in useEffect");
}, [testStringProp]);
return (
<>
<button onClick={() => setTestString("changed from inside component")}>
Change from inside
</button>
<h1>Result here: {testString}</h1>
<p>Change from the ouside works if done before change from the inside</p>
<p>
Once changed from the inside, impossible to change again from the
outside
</p>
</>
);
}
createRoot(root).render(<App />);
<script src="https://cdnjs.cloudflare/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742362235a4429614.html
评论列表(0条)