Contexte

Je vais filtrer une table en fonction des valeurs dans une boîte de sélection. J'ai du mal à comprendre state et props dans react.js. Une fois que j'ai passé la valeur, je peux facilement faire le filtrage, mais j'essaie de le faire de la manière «réagir».

Question

Comment transmettre la valeur de SelectionBox lorsqu'elle est sélectionnée ou remplacée par TableDisplay lorsque l'utilisateur sélectionne l'une des options?

Exemple

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>;
      }
}

Recherche

D'après la lecture, je pense que ce que je dois mettre en œuvre ici est, À l'intérieur SelectionBox

 constructor(props) {
    super(props);

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

Puis accéder à props depuis TableDisplay?

1
wuno 15 janv. 2017 à 17:11

2 réponses

Meilleure réponse

Tout d'abord, pour clarifier votre compréhension de state vs props, vous devez vous référer à cette réponse: Quelle est la différence entre state et props dans React?

Deuxièmement, pour transmettre la valeur du SelectionBox au TableDisplay, vous devez créer une sorte de composant parent TableDisplayContainer qui contient les deux composants. Le TableDisplayContainer stockera la valeur du menu déroulant select dans son état. Pour ce faire, vous devez passer une fonction comme accessoire au SelectionBox qui gérera l'événement onChange de la liste déroulante select (vous pouvez l'appeler handleOnChange par exemple ). La méthode handleOnChange définira la valeur sur l'état du TableDisplayContainer. Une fois qu'il est défini dans l'état, vous pouvez transmettre la valeur au composant TableDisplay comme accessoire.

Voici un exemple rapide de ce que vous pouvez faire:

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>
    )
  }
}
1
Community 23 mai 2017 à 12:24

L'état On React est quelque chose qui est pertinent pour le composant lui-même, et les props lui sont transmis (ou ont une valeur par défaut en cas d'omission). Le guide des événements de gestion explique ma solution ci-dessous:

Vous pouvez transmettre un gestionnaire onChange à selectionBox et l'utiliser sur votre composant TableDisplay

  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>
    }
}

Notez que j'ai utilisé propTypes juste pour m'assurer que je ne n'oublie pas.

0
FabioCosta 15 janv. 2017 à 15:00