React.js如何访问子组件中的输入值

Ale*_*nko 10 javascript ecmascript-6 reactjs

我写了简单的待办事项应用程序,但现在我在访问App(InputForm)的子组件中的输入值时遇到了麻烦.

也许我需要以某种方式重建结构或逻辑以使其有效?

这是我的App组件:

class App extends React.Component {
  constructor (){
      super();
      this.state = {
          items : []
      }
  }

  addTodo ( e ){
    e.preventDefault();

    let itemHeading = this.refs.todoInput.value; // TODO Access to input value
    let itemKey = Date.now();

    const items = this.state.items.slice();

    items.push({
      heading: itemHeading,
      key: itemKey
    })

    this.setState({items: items});
  }
  render() {
    return (
      <div className="app-container">
        <InputForm onSubmit={this.addTodo.bind(this)}></InputForm>
        <TodoItems entries={this.state.items} />
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的InputForm组件:

class InputForm extends React.Component {
  render (){
    return (
      <form onSubmit={this.props.onSubmit}>
        <input
          ref="todoInput"
          type="text"
          placeholder="Type your text here" />
        <button type="submit">Add to list</button>
      </form>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

感谢帮助.

Ori*_*ori 12

转换input受控组件,并在输入中的文本发生更改时更新状态.单击提交时,将值发送给处理程序.

删除refs,因为它们应该用于需要直接访问DOM的东西.这就是文档必须说的反应refs:

在典型的React数据流中,props是父组件与其子组件交互的唯一方式.要修改子项,请使用新道具重新呈现它.但是,在某些情况下,您需要在典型数据流之外强制修改子项.要修改的子项可以是React组件的实例,也可以是DOM元素.对于这两种情况,React都提供了 逃生舱口.

这是一个不需要这个逃生舱的情况,你应该只使用道具.

带评论的工作演示:

const TodoItems = ({ entries }) => (
  <ul>
    {entries.map(({ heading, key }) => (
      <li key={key}>{heading}</li>
    ))}
  </ul>
);

class App extends React.Component {
  state = {
    items : []
  }

  // addTodo will receive the needed value without refs
  addTodo = (heading) => heading !== '' && this.setState(({ items }) => ({
    items: items.concat({ // concat returns a new array
      heading,
      key: Date.now()
    })
  }));

  render() {
    return (
      <div className="app-container">
        <InputForm onSubmit={this.addTodo}></InputForm>
        <TodoItems entries={this.state.items} />
      </div>
    );
  }
}

class InputForm extends React.Component {
  state = {
    input: ''
  };

  // input change handler
  onInput = (e) => this.setState({
    input: e.target.value
  });

  // submit handler
  onSubmit = (e) => {
    e.preventDefault();
    this.props.onSubmit(this.state.input);
  }

  render (){
    return (
      <form onSubmit={this.onSubmit}>
        <input
          // use value and onChange so it will be a controlled component
          value={ this.state.value }
          onChange={ this.onInput }
          type="text"
          placeholder="Type your text here" />
        <button type="submit">Add to list</button>
      </form>
    )
  }
}

ReactDOM.render(
  <App />,
  demo
);
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>
Run Code Online (Sandbox Code Playgroud)