简体   繁体   中英

Using Props And State To Pass Value Of Select Box To Child Component React.JS

Background

I am going to be filtering a table based on the values in a selection box. I am having trouble understanding state and props within react.js . Once I pass the value in I can easily do the filtering but I am trying to do this the "react" way.

Question

How do I pass the value of SelectionBox when it is selected or changed to TableDisplay when the user selects one of the options?

Example

class SelectionBox extends React.Component {
                render() {
                return <div className="filter">
              <label for="business">Filter by Status
                                <select id="business" name="business">
                                    <option value="all">All Requests</option>
                                    <option value="approved">Approved</option>
                                    <option value="pending">Pending</option>
                                    <option value="denied">Denied</option>
                                </select>
                </label>
            </div>;
        }
}

class TableDisplay extends React.Component {
        render() {
            return <div className="wrapper">
            <h1>Requests</h1>
            <SelectionBox /> 
            <div><table className="table">
                    <tr className="seperate"><td>Title</td><td>Status</td><td>Created</td><td>Updated</td><td>Delete</td></tr>
                  {Object.keys(requests).map(function(key) {  
    let styling = "bg-plain";

    if (requests[key].status == "Approved") {
        styling = "bg-success";
    } else if (requests[key].status == "Denied") {
        styling = "bg-danger";
    }

    return <tr className={styling}>
        <td>{requests[key].title}</td>
        <td>{requests[key].status}</td>
        <td>{requests[key].created_at.slice(0, 10)}</td>
        <td>{requests[key].updated_at.slice(0, 10)}</td>
        <td><a href="">Delete</a></td>
    </tr>;

    })}
                    </table>
          </div></div>;
      }
}

Research

From reading I think what I need to implement here is, Inside SelectionBox

 constructor(props) {
    super(props);

    this.state = {
// Something referring to the state of the select box here
    };
  };

Then access props from within TableDisplay ?

First, to clear up your understanding of state vs props you should reference this answer: What is the difference between state and props in React?

Second, to pass the value of the SelectionBox to the TableDisplay you need to create some kind of parent TableDisplayContainer component that contains both components. The TableDisplayContainer will store the value of the select dropdown in its state. To do this, you need to pass a function as a prop to the SelectionBox that will handle the onChange event of the select dropdown (you can call it handleOnChange for example). The handleOnChange method will set the value to the state of the TableDisplayContainer . Once it's set in state, you can pass the value to the TableDisplay component as a prop.

Here's a quick example of what you can do:

class SelectionBox extends React.Component {
  render() {
    return (
      <div className="filter">
        <label for="business">Filter by Status
          <select
            id="business"
            name="business"
            onChange={this.props.handleOnChange}
          >
              <option value="all">All Requests</option>
              <option value="approved">Approved</option>
              <option value="pending">Pending</option>
              <option value="denied">Denied</option>
          </select>
        </label>
      </div>
    );
  }
}

class TableDisplay extends React.Component {
  render() {
    // Do your filtering with this value
    const {selectValue} = this.props;

    return (
      <div className="wrapper">
        <h1>Requests</h1>
        <SelectionBox /> 
        <div><table className="table">
              <tr className="seperate"><td>Title</td><td>Status</td><td>Created</td><td>Updated</td><td>Delete</td></tr>
            {Object.keys(requests).map(function(key) {  
        let styling = "bg-plain";

        if (requests[key].status == "Approved") {
        styling = "bg-success";
        } else if (requests[key].status == "Denied") {
        styling = "bg-danger";
        }

        return <tr className={styling}>
        <td>{requests[key].title}</td>
        <td>{requests[key].status}</td>
        <td>{requests[key].created_at.slice(0, 10)}</td>
        <td>{requests[key].updated_at.slice(0, 10)}</td>
        <td><a href="">Delete</a></td>
        </tr>;

        })}
              </table>
        </div>
      </div>
    );
  }
}
class TableDisplayContainer extends React.Component {
  constructor() {
    super();
    this.state = {
      selectValue: 'all' // use this as default
    }
  }

  handleOnChange(e) {
    this.setState({
      selectValue: e.target.value
    });
  }

  render() {
    const {selectValue} = this.state;

    return (
      <div>
        <SelectionBox
          handleOnChange={this.handleOnChange.bind(this)}
        />
        <TableDisplay
          selectValue={selectValue}
        />
      </div>
    )
  }
}

On React state is something that is relevant to the component itself, and props are passed down to it (or have a default value in case of omission). The handle events guide explains my solution below:

You can pass a onChange handler to selectionBox and use it on your TableDisplay component

  class SelectionBox extends React.Component {
    render () {
      //...
        <select onChange={this.props.onChange}>
          //...
        </select>
      //...
    }
  }
  SelectionBox.propTypes = {
    onChange: PropTypes.func.isRequired
  }
  class TableDisplay extends React.Component {
    constructor(props) {
      super(props)
      this.onSelection = this._onSelection.bind(this)
      this.state = {
        selectValue: null
      }
    }
    _onSelection (ev) {
      this.setState({selectValue:ev.target.value})
    }
    render () {
      //...
      <SelectionBox onChange={this.props.onSelection} />
      //...
      <h1>{'The select value is '+ this.state.selectValue}</h1>
    }
}

Notice that I used propTypes just to make sure that I don't forget.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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