反应js状态管理

时间:2017-06-22 20:36:15

标签: javascript html reactjs react-native state

class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      saveText: '',
    }
    this.handleSaveText = this.handleSaveText.bind(this);
    this.displayText = this.displayText.bind(this);
  }
  handleSaveText(saveText) {
    this.setState({
      saveText: saveText
    })
  }
  render() {
    return (
      <div>
      <Save saveText = {this.state.saveText}
      onSaveTextChange = {this.handleSaveText}
      /> 
      <Display saveText = {this.state.saveText}
      /> </div>
    );
  }
}
class Save extends React.Component {
  constructor(props) {
    super(props);
    this.handleSaveText = this.handleSaveText.bind(this);
  }
  handleSaveText(e) {
    this.props.onSaveTextChange(e.target.value);
  }
  render() {
    return ( <div>
      <input type = "text"
      value = {
        this.props.saveText
      }
      onChange = {
        this.handleSaveText
      }
      /> <input type = "button"
      value = "save"
      onClick = {
        this.displayText
      }
      /> </div>
    );
  }
}
class Display extends React.Component {
  render() {
    var todos = [];
    var todo = this.props.saveText;
    //todos.push(todo);
    return ( <div> {
        todos
      } </div>
    );
  }
}

ReactDOM.render( <Todo / > ,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

我是新手,仍在努力弄清楚状态是如何工作的。我正在尝试实现一个简单的待办事项应用程序,它接受输入并在点击按钮后在屏幕上显示输出。

根据最小的UI表示,我将UI分成两部分,第一部分包含Save类,它有一个输入框和一个按钮。第二个包含一个显示类,它将显示输入框的内容。

我将输入框的值存储在状态中。

如何将该状态传递给Display类并在屏幕上显示值?

Codepen Link

3 个答案:

答案 0 :(得分:2)

这样做:

class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      saveText: '',
      displayText: []
    }
    this.handleSaveText = this.handleSaveText.bind(this);
    this.displayText = this.displayText.bind(this);
  }
  handleSaveText(saveText) {
    this.setState({
      saveText: saveText
    })
  }
  displayText(text) {
    let newDisplay = this.state.displayText;
    newDisplay.push(text);
    this.setState({displayText: newDisplay});
  }
  render() {
    return (
      <div>
      <Save saveText = {this.state.saveText}
      onSaveTextChange = {this.handleSaveText}
      displayText={this.displayText}
      /> 
      <Display displayText = {this.state.displayText}
      /> </div>
    );
  }
}
class Save extends React.Component {
  constructor(props) {
    super(props);
    this.handleSaveText = this.handleSaveText.bind(this);
    this.displayText = this.displayText.bind(this);
  }
  handleSaveText(e) {
    this.props.onSaveTextChange(e.target.value);
  }
  displayText() {
    this.props.displayText(this.props.saveText);
  }
  render() {
    return ( <div>
      <input type = "text"
      value = {
        this.props.saveText
      }
      onChange = {
        this.handleSaveText
      }
      /> <input type = "button"
      value = "save"
      onClick = {
        this.displayText
      }
      /> </div>
    );
  }
}
class Display extends React.Component {
  render() {
    return ( <div> {
        this.props.displayText
      } </div>
    );
  }
}

ReactDOM.render( <Todo / > ,
  document.getElementById('root')
)

你不能在render方法中推送到数组,因为当你再次点击该按钮接收到新的道具时,它将不再存在。我的方法将以前的响应数组保存为“displayText”并将其发送到显示组件。请注意,此方法将整个数组显示为单行,不显示空格。在实践中,你需要通过这样做来映射它:

this.props.displayText.map((text, idx) => (<div key={idx}>{text}</div>));

答案 1 :(得分:1)

这是todo list的工作示例。

&#13;
&#13;
class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: '',
      list: []
    }
    // this.handleSaveText = this.handleSaveText.bind(this);
    this.addTodo = this.addTodo.bind(this);
  }
  handleSaveText(text) {
    this.setState({
      text: text
    })
  }
  addTodo(saveText) {
    var list = this.state.list;
    list.push(saveText);
    this.setState({
      list: list
    });
    // to save to localstorage, uncomment below line
    // window.localStorage.setItem('todos', list);
  }
  render() {
    return ( <
      div >
      <
      Save text = {
        this.state.text
      }
      onClick = {
        this.addTodo
      }
      />  <
      Display list = {
        this.state.list
      }
      /> < /
      div >
    );
  }
}
class Save extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: this.props.text || '',
    }
    this.onChange = this.onChange.bind(this);
    this.addToTodo = this.addToTodo.bind(this);
  }
  onChange(e) {
    this.setState({
      input: e.target.value
    });
  }
  addToTodo() {
    this.props.onClick(this.state.input);
    this.setState({
      input: ''
    });
  }
  render() {
    return ( < div >
      <
      input type = "text"
      value = {
        this.state.input
      }
      onChange = {
        this.onChange
      }
      /> <input type = "button"
      value = "save"
      onClick = {
        this.addToTodo
      }
      /> </div >
    );
  }
}
class Display extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        todos: []
      }
    }

    componentWillReceiveProps(nextProps) {
      this.setState({
        todos: nextProps.list
      });
    }

    render() {
      var i = 1;
      var renderList = this.state.todos.map((name) => {
        return <div key = {
          i++
        } > {
          name
        } < /div>;
      });

      return ( < div > {
          renderList
        } < /div>);
      }
    }

    ReactDOM.render( < Todo / > ,
      document.getElementById('root')
    )
&#13;
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>My React Project on CodePen</title>

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/4.1.0/sanitize.css">
  <link rel="stylesheet" href="css/style.processed.css">
</head>

<body>

  <div id="root"></div>

  <script src="https://npmcdn.com/react@15.3.0/dist/react.min.js"></script>
  <script src="https://npmcdn.com/react-dom@15.3.0/dist/react-dom.min.js"></script>

</body>

</html>
&#13;
&#13;
&#13;

如果您正在尝试创建一个待办事项列表,您可以通过在主TODO组件中添加数组列表来调整一点,然后向下显示组件。

保存组件,您只需处理输入更改和点击功能。

很简单。

答案 2 :(得分:0)

您必须使用:

componentWillReceiveProps(nextProps)
显示组件中的

这是一个有效的例子:

class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      todos: []
    }
    this.handleSaveText = this.handleSaveText.bind(this);
  }
  handleSaveText(saveText) {
    let todos = this.state.todos;
    todos.push(saveText);
    this.setState({
      todos: todos
    });
  }
  render() {
    return (
      <div>
      <Save
      onSaveTextClick = {this.handleSaveText}
      /> 
      <Display todos = {this.state.todos}
      /> </div>
    );
  }
}
class Save extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      saveText: ''
    }
    this.handleSaveText = this.handleSaveText.bind(this);
    this.handleChangeText = this.handleChangeText.bind(this);
  }
  handleChangeText(e){
    this.setState({saveText: e.target.value});
  }
  handleSaveText(e) {
    this.props.onSaveTextClick(this.state.saveText);
  }
  render() {
    return ( <div>
      <input type = "text"
      onChange = {
        this.handleChangeText
      }
      /> <input type = "button"
      value = "save"
      onClick = {
        this.handleSaveText
      }
      /> </div>
    );
  }
}
class Display extends React.Component {

  constructor(props){
    super(props);
    this.state = {
      todos: []
    }
  }

  componentWillReceiveProps(nextProps){
    this.setState({todos: nextProps.todos});
  }
  
  render() {
    let todos = this.state.todos.map((todo)=>{return <div>{todo}</div>});
    return ( <div> {
        todos
      } </div>
    );
  }
}

ReactDOM.render( <Todo / > ,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>