从孩子更改父项的道具/状态

时间:2018-08-09 18:57:38

标签: reactjs react-props react-state-management

我目前正在学习REACT,以创建网络应用。 在这个应用程序中,我有一个处于父级状态的selectedCharacters列表,在每个子级组件中,我都有一个播放器名称的输入。 我正在努力更新处于家长状态的玩家名称。

class Game extends React.Component {
  state = {
    selectedCharacters: [{"name":"Loup Garou","imgName":"base_loup.png","uniqueKey":"loup","playerName":""},{"uniqueKey":"voyante","imgName":"base_voyante.png","name":"Voyante","maxInGame":1,"left":1}]
  };
  changePlayerName = (char, newName) => {
    char.playerName = newName;
  };
  render() {
    const { selectedCharacters } = this.state;
    return(<CharactersSelection selectedCharacters={selectedCharacters} />);  
  }
}

const CharactersSelection = props => {
  return (
    <div className="row col-12 char-list">      
      <div className="col-md-9 col-xl-10 char-selected pad-r-10 pad-l-10">
        <div className="row char-selected-content">
          {props.selectedCharacters.map((char, i) => (
            <CharacterCardSelected key={i} imgName={char.imgName} name={char.name} playerName={char.playerName}/>
          ))}
        </div>
      </div>
    </div>
  );
};

const CharacterCardSelected = props => {
  return (
    <div className="d-flex char-card-selected" id={props.id}>
      <img alt={props.imgName} className="char-img-sm" src=require("../../public/images/" + props.imgName)}/>
      <div className="char-card-selected-txt">
        <div>
          <input
            type="text"
            className="form-control player-name"
            placeholder="Nom joueur..."
            value={props.playerName}
            onChange={e => {console.log(e)}}
          />
        </div>
      </div>
    </div>
  );
};

我们将不胜感激。

4 个答案:

答案 0 :(得分:3)

您要做的是将changePlayerName函数作为对CharactersSelection的支持,然后将其进一步传递给CharacterCardSelected组件。现在onChange of CharacterCardSelected调用方法this.props.changePlayerName(name);

class Game extends React.Component {
  state = {
    selectedCharacters: [{"name":"Loup Garou","imgName":"base_loup.png","uniqueKey":"loup","playerName":""},{"uniqueKey":"voyante","imgName":"base_voyante.png","name":"Voyante","maxInGame":1,"left":1}]
  };
  changePlayerName = (char, newName) => {
    char.playerName = newName;
  };
  render() {
    const { selectedCharacters } = this.state;
    return(<CharactersSelection selectedCharacters={selectedCharacters} onChange={this.changePlayerName} />);  
  }
}

const CharactersSelection = props => {
  return (
    <div className="row col-12 char-list">      
      <div className="col-md-9 col-xl-10 char-selected pad-r-10 pad-l-10">
        <div className="row char-selected-content">
          {props.selectedCharacters.map((char, i) => (
            <CharacterCardSelected key={i} imgName={char.imgName} name={char.name} playerName={char.playerName} onChange={(newName) => {props.onChange(char,newName)}}/>
          ))}
        </div>
      </div>
    </div>
  );
};

const CharacterCardSelected = props => {
  return (
    <div className="d-flex char-card-selected" id={props.id}>
      <img alt={props.imgName} className="char-img-sm" src=require("../../public/images/" + props.imgName)}/>
      <div className="char-card-selected-txt">
        <div>
          <input
            type="text"
            className="form-control player-name"
            placeholder="Nom joueur..."
            value={props.playerName}
            onChange={e => {
              console.log(e);
              props.onChange(e.target.value)
            }}
          />
        </div>
      </div>
    </div>
  );
}; 

答案 1 :(得分:1)

扩大迈克尔的答案:

class Parent extends React.Component {
  state = { someValue: "" }

  onChangeValue = (event) => {
    this.setState({ someValue: event.target.value })
  }

  render () {
    const { someValue } = this.state
    return (
      <Child onChangeValue={this.onChangeValue} value{someValue}/>
    )
  }
}

class Child extends React.Component {
  render() {
    return (
      <input 
        onChange={this.props.onChangeValue} 
        value={this.props.value}
      />
    )
  }
}

这是React中一种常见的模式,称为Lifting State Up

答案 2 :(得分:0)

尝试在父组件中创建一个函数,然后将其传递给Child组件。将名称分配给父级中的状态变量,然后将其传递给子级组件。

答案 3 :(得分:0)

将changePlayerName函数传递给最低的子级。从那里开始,您需要触发父组件的setState,以更改播放器的名称。

class Game extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            selectedCharacters: [{
              "name": "LoupGarou",
              "imgName": "base_loup.png",
              "uniqueKey": "loup",
              "playerName": ""
            }, {
              "uniqueKey": "voyante",
              "imgName": "base_voyante.png",
              "name": "Voyante",
              "maxInGame": 1,
              "left": 1
            }]
          }
        }
        changePlayerName = (index, newName) => {
          this.setState({
            selectedCharacters[index].playerName: newName
          });
        };
        render() {
          const {
            selectedCharacters
          } = this.state;
          return ( < CharactersSelection selectedCharacters = {
              selectedCharacters
            }
            changePlayerName = {
              this.changePlayerName
            }
            />);
          }
        }
        const CharactersSelection = props => {
            return ( < div className = "row col-12 char-list" > < div className =
                "col-md-9 col-xl-10 char-selected pad-r-10 pad-l-10" > < div className =
                "row char-selected-content" > {
                  props.selectedCharacters.map((char, index) => ( <
                      CharacterCardSelected key = {
                        index
                      }
                      imgName = {
                        char.imgName
                      }
                      changePlayerName = {
                        props.changePlayerName
                      }
                      name = {
                        char.name
                      }
                      playerName = {
                        char.playerName
                      }
                      />))
                    } < /div> < /div > < /div>);
                  };
                  const CharacterCardSelected = props => {
                    return ( < div className = "d-flex char-card-selected"
                      id = {
                        props.id
                      } > < img alt = {
                        props.imgName
                      }
                      className = "char-img-sm"
                      src = require("../../public/images/" + props.imgName)
                    }
                    /> < div className = "char-card-selected-txt" > < div > < input
                    type = "text"
                    className = "form-control player-name"
                    placeholder = "Nom joueur..."
                    value = {
                      props.playerName
                    }
                    onChange = {
                      (e) => props.changePlayerName(props.key, e.target.value)
                    }
                    /> < /div > < /div> < /div > );
                };