reactjs - How to change value from either inside or outside a component - Stack Overflow

I want to be able to change a value from both inside and outside a component.Below is a copy of my att

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
Add a comment  | 

1 Answer 1

Reset to default 1

The 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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信