javascript - 在 React 中从子组件更改 prop 后,等待从父组件更改 prop

标签 javascript reactjs

我已经将 React 中的 Child 类组件重写为功能组件。这是简化的代码示例。
当然,通常情况下,这是一个简化的代码,更多的事情是用父组件中的值完成的。这就是为什么我们在那里拥有并需要它。

const Parent = (props) => {
  const [value, setValue] = useState(null);

  const handleChange = (newValue) => {
    // do something with newValue and probably change it
    // store the result in `newChangedValue`
    setValue(newChangedValue);
  }

  return (
    <Child value={value} onChange={handleChange}/>
  );
}

const Child = (props) => {
  const {value} = props;

  // This solution does not work for me,
  // because it's always triggered, when
  // `value` changes. I only want to trigger
  // `logValueFromProp` after clicking the
  // Button.
  useEffect(() => {
    logValueFromProp();
  }, [value]);

  const handleClick = () => {
    // some calculations to get `newValue`
    // are happening here
    props.onChange(newValue);
    logValueFromProp();
  }

  const logValueFromProp = () {
    console.log(prop.value);
  }

  return (
    <Button onClick={handleClick} />
  );
}
我想要做的是记录一个属性值,但前提是它通过单击按钮进行了更改。所以只需使用 useEffect对我不起作用。
在将子组件更改为功能组件之前,在我调用 logValueFromProp() 之前,该属性具有其新值。 .后来就不行了。我想这是一些时间的原因,我很幸运在调用函数之前更新了属性。
所以问题是:你将如何解决这种情况?我想到的一个解决方案是我在单击按钮时设置的子组件中的状态,而在 useEffect 中,我只在设置状态时调用该函数,然后重置状态。但这对我来说并不是最佳解决方案......

最佳答案

三种可能的解决方案

  • 通行证logValueFromProp该值直接 - 但在评论中,您已经解释了该值可能会在设置在子组件上之前被父组件稍微修改,这将使其不适用。
  • 在引用中使用标志。但是如果 parent 不总是改变 Prop ,那将是不可靠的。
  • 让父级在其 handleChange 中接受回调.

  • #1
    如果可能,我会将值直接传递给 logValueFromProp当你想记录它时。这是简单直接的解决方案:
    const Child = (props) => {
      const {value} = props;
    
      const handleClick = () => {
        props.onChange(newValue);
        logValueFromProp(newValue);
      };
    
      const logValueFromProp = (newValue = prop.value) {
        console.log(newValue);
      };
    
      return (
        <Button onClick={handleClick} />
      );
    };
    
    但在评论中,您曾说过新值可能与您所说的 props.onChange 不完全相同。和。
    #2
    您可以使用 ref记住您是否要在下一次调用组件函数时记录它(这可能是在它更改之后):
    const Child = (props) => {
      const {value} = props;
      const logValueRef = useRef(false);
    
      if (logValueRef.current) {
        logValueFromProp();
        logValueRef.current = false;
      }
    
      const handleClick = () => {
        props.onChange(newValue);
        logValueRef.current = true;
      };
    
      const logValueFromProp = () {
        console.log(prop.value);
      };
    
      return (
        <Button onClick={handleClick} />
      );
    };
    
    使用 ref 而不是 state 成员意味着当您清除标志时,它不会导致重新渲染。 (您的组件函数仅在 handleClick 之后调用,因为父函数更改了 value 属性。)
    请注意,如果父组件 没有 调用时更改值 prop.onChange ,ref 标志将保持设置,然后您的组件将错误地记录下一个更改的值,即使它不是来自按钮。出于这个原因,尝试将日志记录移动到父级可能是有意义的,它知道它如何响应 onChange .
    #3
    鉴于上述两个问题,最可靠的解决方案似乎是修改 ParenthandleChange以便它使用可能修改的值调用回调:
    const Parent = (props) => {
      const [value, setValue] = useState(null);
    
      const handleChange = (newValue, callback) => {
        //                          ^^^^^^^^^^−−−−−−−−−−−−−−−−− ***
        // do something with newValue and probably change it
        // store the result in `newChangedValue`
        setValue(newChangedValue);
        if (callback) {                                      // ***
            callback(newChangedValue);                       // ***
        }                                                    // ***
      };
    
      return (
        <Child value={value} onChange={handleChange}/>
      );
    };
    
    const Child = (props) => {
      const {value} = props;
    
      const handleClick = () => {
        props.onChange(newValue, logValueFromProp);
        //                     ^^^^^^^^^^^^^^^^^^−−−−−−−−−−−−−− ***
      }
    
      const logValueFromProp = () {
        console.log(prop.value);
      };
    
      return (
        <Button onClick={handleClick} />
      );
    };
    

    关于javascript - 在 React 中从子组件更改 prop 后,等待从父组件更改 prop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69361431/

    相关文章:

    javascript - 阴影模糊的 Fabric.js 边界框

    javascript - 我如何对对象进行冒泡排序?

    reactjs - 将数据从 child 发送到 parent React

    javascript - 如何避免与 React hooks 相关的范围问题

    javascript - 我如何从另一个网站获得 "getImageData"?安全错误 : DOM Exception 18

    javascript - 如何从 Bootstrap 导航栏中删除默认填充

    reactjs - 如何在 _document 中添加自定义属性和扩展 DocumentInitialProps 类型?

    javascript - Formik 的 handleChange 抛出 "TypeError: null is not an object (evaluating ' _a.type' )"on DateInput' s onChange

    css - 如何放大material-ui iconButtons中的SVG图标?

    javascript - 在 JavaScript 中按字符串属性值对对象数组进行分组?