我有一个组件:
React = require 'react'
module.exports = Toolbar = React.createClass
proptypes:
initialUrl: React.PropTypes.string
onUrlChange: React.PropTypes.func
getInitialState: ->
url: @props.initialUrl
handleUrlChange: (e) ->
@setState(url: e.target.value)
handleUrlKeyUp: (e) ->
if e.which == 13
e.target.blur()
if (url = @state.url.trim())? and url isnt @props.initialUrl
@props.onUrlChange?(url)
@setState {url}
if e.which == 27
@setState {url: @props.initialUrl}
render: ->
<div className="component-toolbar clearfix">
<input type="text" value={@state.url} onChange={@handleUrlChange} onKeyUp={@handleUrlKeyUp}/>
</div>
该组件的工作方式如下:
initialUrl
呈现输入。onUrlChange
。 @state.url
将返回原始值(initialUrl
)到目前为止一切顺利。
但是当我更改道具或上层组件的状态时,派生initalUrl
,那么组件具有相同的状态并且不会被重新渲染。这是因为getInitialState
只被调用一次。但是解决这个问题的正确方法是什么?
谢谢。
答案 0 :(得分:2)
如果您遵循使用initialValue做出反应的输入方式,那么您当前的代码具有相同的行为。只有重新安装会导致它更改网址。
作为替代方案,如何让父母管理状态,并添加onSubmit事件?
module.exports = Toolbar = React.createClass
propTypes:
url: React.PropTypes.string
onChange: React.PropTypes.func
onSubmit: React.PropTypes.func
onReset: React.PropTypes.func
handleUrlChange: (e) ->
@props.onChange(e.target.value)
handleUrlKeyUp: (e) ->
url = @props.url.trim()
if e.which == 13
e.target.blur()
if url?
@props.onChange?(url)
@props.onSubmit?(url)
if e.which == 27
@props.onReset()
render: ->
<div className="component-toolbar clearfix">
<input type="text" value={@props.url} onChange={@handleUrlChange} onKeyUp={@handleUrlKeyUp}/>
</div>
当然这会改变你组件的api,但不要害怕!因为您从一个灵活的无状态组件开始,然后可以将其包装在覆盖90%用例的有状态组件中(例如在es6 / 7中)。
class StatefulToolbar extends React.Component {
static propTypes = {
initialUrl: React.PropTypes.string,
onUrlChange: React.PropTypes.func
};
constructor(props){
super();
this.state = {url: props.initialUrl};
}
render(){
return (
<Toolbar
value={this.state.url}
onChange={(url) => this.setState({url})}
onReset={() => this.setState({url: this.props.initialUrl})}
onSubmit={(url) => this.props.onUrlChange(url)}
/>
);
}
}
如果要根据其他事件控制值更新,则应为该特定情况创建包装器,而不是使Toolbar复杂化。
旁注:propTypes,而不是proptypes。