在构造函数中对props进行undefined反应并存在于render中

时间:2017-10-19 12:33:23

标签: javascript reactjs

我正在尝试创建受控文本区域。

class TextArea extends React.Component {
  constructor(props) {
    super(props);
    this.state= {
        text: this.props.initial
    };
    this.handleChange = this.handleChange.bind(this);
  }

handleChange(event) {
    //some handle
}

render() {
    return (
        <textarea
          value={this.state.text}
          placeholder={this.props.initial}
          onChange={this.handleChange}
        />
    );
  }
}

出于某种原因,如果我在控制台.log中构造函数中的this.props.initial,我得到一个未定义的。

但占位符有效。

我想做的是抛弃占位符并将初始值设置为用户可以编辑,复制和交互的值。 (基本上是普通文本而不是占位符,但我不能这样做,因为它不起作用)

我做错了什么?

编辑: 我将props.initial传递给textarea的方式:

<TextArea
  initial={this.state.json.initial}
  text={this.state.json.text}
  changeHandler={this.handleChange}
/>

我从$ .getJSON调用获取json,我认为textarea在json调用完成之前呈现。有没有办法只在componentWillMount函数之后运行render函数?

3 个答案:

答案 0 :(得分:1)

从构造函数中的this删除this.props,因为您可以从其参数列表中访问props

class TextArea extends React.Component {
  constructor(props){
    super(props)
    
    this.state = {
      text: props.initial,
    }
    
    this.handleChange = this.handleChange.bind(this)
  }
  
  handleChange(event){
    this.setState({ text: event.target.value })
  }
  
  render(){
    return (
      <div>
        <div>Initial text: {this.props.initial}</div>
        <textarea
          value={this.state.text}
          placeholder={this.props.initial}
          onChange={this.handleChange}
        />
      </div>
    )
  }
}

ReactDOM.render(
  <TextArea />,
  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>

答案 1 :(得分:0)

要理解的重要部分是构造函数已经将props作为参数接受,因此您可以在构造函数中直接访问props props。只要您在构造函数

中,就不需要通过this.props访问它
constructor(props) {
  super(props);
  this.state= {
    text: props.initial
  }
}

上面的代码应该可以正常工作

但是,这是构建像TextArea这样的组件的更好方法,它也应该解决props.initial没有运行时值的问题

首先,您需要在父组件

中准备handleChange方法
class ParentComponent extends Component {
  constructor(props) {
    super(props)
    this.state = {
      myTextArea: ''
    }

    this.handleChange = this.handleChange.bind(this)
  }

  handleChange (e) {
    this.setState({myTextArea: e.target.value})
  }

  render () {
    return (
      <TextArea
        value={myTextArea}
        onChange={this.handleChange}
      />
    )
  }
}

在文本区域组件上,您可以在定义textarea的onchange方法时引用通过props传递的onchange方法。

<textarea
  value={this.props.value}
  placeholder="Something"
  onChange={this.props.handleChange}
/>

这种方法的好处是,一个,调用textarea的那个将始终具有更新的值,并且两个,这个子元素不需要具有状态。它使得管理大型反应应用程序变得更容易,并且一旦您开始尝试实施Redux或类似的框架来为您处理您的状态,它就会有正确的思维方式

答案 2 :(得分:0)

你必须保证this.props.inital存在:

{ this.state.json && this.state.json.initial &&
  <TextArea initial={this.state.json.initial} text={this.state.json.text} changeHandler={this.handleChange}/>
}