【问题标题】:React js state managementReact js 状态管理
【发布时间】:2017-11-26 07:05:51
【问题描述】:

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 类并在屏幕上显示值?

代码笔Link

【问题讨论】:

  • 你在 javascript 控制台中得到了什么?如果您在 Display 渲染中 console.log(todo); 怎么办?
  • 没什么,整个 UI 消失了@mkaatman
  • F12,控制台为空,UI消失?
  • Uncaught TypeError: Cannot read property 'bind' of undefined ----我得到@mkaatman
  • 是哪一行?你有三个绑定。

标签: javascript html reactjs react-native state


【解决方案1】:

你必须使用:

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>

【讨论】:

  • 我想将待办事项存储在本地存储中。单击按钮后我该怎么做
【解决方案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) =&gt; (&lt;div key={idx}&gt;{text}&lt;/div&gt;));

【讨论】:

    【解决方案3】:

    这是待办事项列表的工作示例。

    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')
        )
    <!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>

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

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

    足够简单。

    【讨论】:

      猜你喜欢
      • 2015-06-23
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 2017-08-28
      • 2020-06-24
      • 1970-01-01
      相关资源
      最近更新 更多