javascript - 提升状态向上 : Communicating from child component and upward

标签 javascript reactjs

当我尝试从子组件修改基本组件的变量时。我发现我只能通过严格执行以下操作来做到这一点:

1:基础组件必须定义了一个事件处理程序,严格来说是一个变量onVariableChange事件处理程序,并将其分配给本地函数

2:基础组件必须有自定义属性variable将与上述 onVariableChange 链接功能

3:子组件现在可以调用this.props.onVariableChange()进行适当的修改(从子到基)

在基本声明中:
changeFn(){ //do Something }
基地的渲染:

return <div> <Child variable={this.stateSomeVar} onVariableChange={this.changeFn} />

在 child :
this.props.onVarChange();

这是为什么?为什么我们不能不使用自定义属性而直接从 child 调用自定义函数到 base ?

我是否错误地理解了 React 的文档?

在基地:
childFnAnsweredByBase(){
   ...
}
render(){
  return <Child callFromChildFn={this.childFnAnsweredByBase} />
}

引用:
https://reactjs.org/docs/lifting-state-up.html

最佳答案

When I try to modify a base component's variable from a child component. I find that I can only do it by strictly doing the following:



我认为您的意思是变量、基本或更准确的父组件状态。

1: Base component must have defined an event handler, strictly a variable onVariableChange event handler, and have it assigned to a local function



我不知道你所说的“严格”是什么意思,但是为了做到这一点, parent 应该有一个处理程序方法。这里的名称并不重要,只需将其正确传递给您的子组件即可。

2: Base component must have custom attribute variable that will be linked with the above onVariableChange function



此变量或状态属性不需要链接到任何地方,您不必将其传递给您的子组件。如果子组件将使用它,是的,您可以传递,但为了在父组件中更改它,不需要将其传递给子组件。

this.props.onVarChange();

Why is that? Why can't we just call the custom function from child to base directly without the use of custom property?



如果您的意思是说“属性”值本身,那么您不需要将其传递给 child 。但是,如果你的意思是 props , 那么你应该这样使用,因为这个函数是 child 的 props 的一部分.

这是一个不传递“变量”的示例:

const Child = (props) => (
  <div>
    <input onChange={props.callFromChildFn} />
  </div>
);


class App extends React.Component {
  state = {
    someVar: "initial value",
  }
  childFnAnsweredByBase = event =>
    this.setState({ someVar: event.target.value })

  render() {
    return (
      <div>
        <Child callFromChildFn={this.childFnAnsweredByBase} />
        <p>someVar is: {this.state.someVar}</p>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>


Am I incorrectly understanding the React's documentation?



可能是。就个人而言,我不喜欢文档的那部分。他们试图在那里解释一个极端情况。两个子组件正在与某个父级的状态同步,并在适当的情况下显示此值。就像,其中一个将这个值显示为华氏度,另一个将其显示为摄氏度。这就是为什么他们将状态变量(经过一些转换)传递给这些组件的原因。

在上面的示例中,我们没有在子组件中使用此状态变量,这就是我们不需要它的原因。这是一个例子(只是一个简单的、愚蠢的例子),展示了我们如何使用它以及为什么父级传递它。

const Child = (props) => {
  const { someNum, multiplyTheNumberBy, by } = props;
  const handleMultiply = () => {
    const newNum = someNum * by;
    multiplyTheNumberBy( newNum );
  }
  return (
    <div>
      <button onClick={handleMultiply}>Multiply Number By {by}</button>
    </div>
  );
}


class App extends React.Component {
  state = {
    someNum: 1,
  }
  
  multiplyTheNumberBy = valueFromChild =>
    this.setState({ someNum: valueFromChild })

  render() {
    return (
      <div>
        <Child 
        multiplyTheNumberBy={this.multiplyTheNumberBy}
        someNum={this.state.someNum}
        by={10}
        />
        <Child
          multiplyTheNumberBy={this.multiplyTheNumberBy}
          someNum={this.state.someNum}
          by={100}
        />
      <p>someNum is: {this.state.someNum}</p>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>


评论后更新

Also, why do we have to assign const localFn = props.CallFromChildFn ? why can't we just invoke this.props.CallFromChildFn directly? Or is it supposed to be props.CallFromChildFn?



第一件事。我们使用 this在类组件中,因此对于功能组件,没有必要。我们可以使用我们的 Prop 作为props.something而不是 this.props.something .

现在,第二个问题是关于出于性能原因应用最佳实践。对于小型应用程序,这可能不是问题,但对于具有多个子级的大型应用程序,组件可能会出现问题。

在 JSX 属性中定义函数时,如果使用箭头函数并立即调用它们,或者将其绑定(bind)到 this为了正确使用它,在每次渲染中都会重新创建此功能。这就是为什么使用对这个函数的引用而不是立即以某种方式调用它们或使用绑定(bind)。

例子。

想想我的第一个例子。
<input onChange={props.callFromChildFn} />

在这里,我使用了我的函数的引用并且它有效。因为我在这里没有调用任何函数,所以每次渲染我的组件时都不会重新创建它。我会以这种方式使用它:
<input onChange={e => props.callFromChildFn( e )} />

在这里,我们使用 onChange 的回调。作为箭头函数。它接受一个事件并将其传递给我们的 callFromChildFn功能。这也有效。但是,由于我们在这里使用了箭头函数,因此在每次渲染中都会创建此函数。

让我们看看我的第二个例子。
const { someNum, multiplyTheNumberBy, by } = props;
  const handleMultiply = () => {
    const newNum = someNum * by;
    multiplyTheNumberBy( newNum );
  }
  return (
    <div>
      <button onClick={handleMultiply}>Multiply Number By {by}</button>
    </div>

同样,我没有直接使用我的函数,而是在这里定义了一个处理函数并使用它的引用。有了这个新创建的函数,我可以进行乘法运算并使用我的 multiplyTheNumber从我的 Prop 中获取函数并将计算值传递给它。但同样,我会使用这样的东西:
const { someNum, multiplyTheNumberBy, by } = props;
  return (
    <div>
      <button onClick={() => multiplyTheNumberBy(someNum * by)}>Multiply Number By {by}</button>
    </div>

如您所见,无需创建新函数,我们可以使用 onClick回调函数并使用我们的multiplyTheNumberBy从我们的 Prop 中直接进行乘法运算。但是,这个函数也在每次渲染中重新创建。

是的,使用引用方法,我们使用了更多代码,对于小型应用程序,这可能不是必需的。但是,我喜欢用这种方式。

关于javascript - 提升状态向上 : Communicating from child component and upward,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51904586/

相关文章:

javascript - 提交特定表单而不使用页面中存在的 javascript

javascript - 浏览器中的自动增量验证短信代码(otp || 2fa)

javascript - 如何引用package.json中的 `main`字段值?

javascript - 如何从对象类型 State 的字段捕获 onChange 事件

reactjs - 让 Nextjs 忽略 babel.config.js

javascript - 使用 ng-template 在 Angular 10 中仅显示博客中的相关条目

javascript - 奇怪的 HTML/JS/CSS 滚动条功能难题

javascript - 如何在 react 中使用 tabs.executeScript

javascript - React 容器中在哪里初始化 Socket 对象?

reactjs - 如何防止 axios.interceptors.response.use 崩溃错误处理?