简体   繁体   English

将状态传递给父组件

[英]Passing state to parent component

I'm refactoring some code to make a more aesthetically pleasing render of a table. 我正在重构一些代码,以使表更美观。 I will link a codesandbox that shows both the old and new implementations. 我将链接一个显示旧实现和新实现的代码框。

So if you select the two dropdowns at the top, in the old implementation section when you check one of the boxes next to the fieldName you will see 3 additional input boxes appear; 因此,如果您选择顶部的两个下拉菜单,则在旧的实施部分中,当您选中fieldName旁边的其中一个框时,您将看到另外三个输入框; lengthType , size , and maxArrayElements . lengthTypesizemaxArrayElements The change handlers for these are in the main component index.js . 这些更改处理程序位于主要组件index.js

I have since made a separate component TableRowWithCheckbox that introduces some new functionality that uses a checkbox to keep track of what row is selected. 我已经创建了一个单独的组件TableRowWithCheckbox ,它引入了一些新功能,使用复选框来跟踪选择的行。

In the new implementation (the table) I have decided to render the 3 inputs mentioned above, inside the table. 在新的实现(表格)中,我决定在表格中呈现上面提到的3个输入。 I'm having trouble keeping track of the inputs since they are now moved inside this new component. 我无法跟踪输入,因为它们现在被移动到这个新组件中。

Should I initialize state for lengthType , size, and maxArrayElements inside this new component then have the change handler inside the main component? 我应该在这个新组件中初始化lengthTypesize,maxArrayElements状态,然后在主组件中包含更改处理程序吗? Or initialize the state values AND have the change handles in the main component? 或初始化状态值并在主要组件中具有更改句柄?

TableRowWithCheckbox component below. TableRowWithCheckbox组件如下。

import React, { Component } from "react";
import { Table, Checkbox, Dropdown, Input } from "semantic-ui-react";

const lengthTypeOptions = [
  { key: "fixed", text: "Fixed", value: "fixed" },
  { key: "variable", text: "Variable", value: "variable" }
];

export default class TableRowWithCheckbox extends Component {
  constructor(props) {
    super(props);
    const { initialState } = this.props;
    this.state = {
      fieldCheckbox: initialState
    };
  }

  checkbox = () => {
    this.setState({ fieldCheckbox: !this.state.fieldCheckbox }, () => {
      console.log("checkbox --> ", this.state.fieldCheckbox);
      const {
        name,
        dataType,
        isArray,
        position,
        box,
        lengthType,
        size,
        maxArrayElements
      } = this.props;
      box({
        name,
        dataType,
        isArray,
        position,
        isChecked: this.state.fieldCheckbox,
        lengthType,
        size,
        maxArrayElements
      });
    });
  };

  render() {
    const {
      name,
      dataType,
      isArray,
      position,
      lengthType,
      size,
      maxArrayElements
    } = this.props;
    const { fieldCheckbox } = this.state;
    return (
      <>
        <Table.Row>
          <Checkbox
            style={{ marginTop: "20px" }}
            checkbox
            onChange={this.checkbox}
          />
          <Table.Cell>{name}</Table.Cell>
          <Table.Cell>{dataType}</Table.Cell>
          <Table.Cell>{JSON.stringify(isArray)}</Table.Cell>
          <Table.Cell>{position}</Table.Cell>
          <Table.Cell>
            <Dropdown
              placeholder="Pick a length Type:"
              clearable
              selection
              search
              fluid
              noResultsMessage="Please search again"
              multiple={false}
              value={this.state.lengthType}
              options={lengthTypeOptions}
              header="CHOOSE A LENGTH TYPE"
              onChange={this.props.updateLengthType}
              required
            />
          </Table.Cell>
          <Table.Cell>
            <Input
              onChange={this.props.onSizeChange}
              type="number"
              name="size"
              min="1"
              placeholder="1"
              required
            />
          </Table.Cell>
          <Table.Cell>
            <Input
              onChange={this.props.onChangeMaxArrayElements}
              type="number"
              name="maxArrayElements"
              placeholder="1"
              min="1"
              max="100"
              required
            />
          </Table.Cell>
        </Table.Row>
      </>
    );
  }
}

Codesandbox link here 代码框在这里链接

The convention for passing state to a parent is via callback methods. 将状态传递给父级的约定是通过回调方法。 The parent should pass the child a function to call when there is something to update; 当有更新的东西时,父进程应该向子进程传递一个函数来调用; and the parameters passed into the function would be ones you want to set in the parent state. 并且传递给函数的参数将是您要在父状态中设置的参数。 That way the parent's method would just need to call this.setState() with the params coming into the function. 这样父进程的方法只需要调用this.setState()并使用参数进入函数。

In React, idea is to lift your state up where you will actually modify it. 在React中,想法是将你的状态提升到实际修改它的位置。 So in your case, it makes sense to have your state and change handlers both inside of your main component. 因此,在您的情况下,在主组件内部使用状态和更改处理程序是有意义的。

Pass a function as prop to your component, and give your input the same names as in the parent state. 将函数作为prop传递给组件,并为输入提供与父状态相同的名称。

onChange = (e) => {
  this.setState({
    [e.target.name]: e.target.value
  })
}

Use the function in your inputs 使用输入中的功能

<input onChange={this.props.onChange} ... />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM