复合 本质上是对组件的一种组织、管理方式,实现代码的封装
Mixin(混入):就是将抽离出组件相同逻辑处理部分混入到组件中,实现代码的复用
一、组件嵌套
想要在父组件中嵌套子组件,和引用HTML
标签一样,<子组件名> ... </子组件名>
或 <子组件名 />
【注意1】render
中return
的HTML
标签都必须有个最外层的标签包裹
【注意2】子组件必须包裹在一个HTML
标签内
//正确的写法
var Children = React.creatClass({
render: function(){
return( //有最外层标签包裹
<div>i am from Children</div>
)
}
})
var Parent = React.createClass({
render: function(){
return( //子组件必须包裹在一个`HTML`标签内
<div>
<Children fromParent={}/>
</div>
)
}
})
错误的写法如下:
//错误一:在Parent中,子组件没有包裹在一个HTML标签内
var Parent = React.createClass({
render: function(){
return(
<Children fromParent={}/>
)
}
})
//错误二:在Children中,两个<div>没有包裹在一个HTML标签内
var Children = React.creatClass({
render: function(){
return(
<div>Oops</div>
<div>i'm from Children</div>
)
}
})
二、委托
子组件委托父组件做xxx
在父组件定义一个方法storeData
,该方法的参数为你想要传递的数据,然后使用this.setState()
进行修改,再将该方法传递给子组件,子组件调用的时候就能够修改父组件的state
,但本质还是父组件自己修改自己的state。
var Parent = React.createClass({
getInitialState: function(){
return{
data: 'parent'
}
},
storeData: function(new_data){
this.setState({data: new_data})
},
render: function(){
return(
<div>
<Children fromParent={this.state.data} storeData={this.storeData}/>
</div>
)
}
})
var Children = React.createClass({
handleClick: function(){
var data = 'new data!!!';
this.props.storeData(data);
},
render: function(){
return(
<div onClick={this.handleClick}>{this.props.fromParent}</div>
)
}
})
实例二
var GenderSelect = React.createClass({
render: function() {
return <select onChange={this.props.handleSelect}>
<option value="0">男</option>
<option value="1">女</option>
</select>
}
})
var SignupForm = React.createClass({
getInitialState: function() {
return {
name: '',
password: '',
gender: '',
}
},
handleChange: function(name, event) {
var newState = {}
newState[name] = event.target.value
this.setState(newState)
},
handleSelect: function(event) {
this.setState({gender: event.target.value})
},
render: function() {
console.log(this.state)
return <form>
<input type="text" placeholder="请输入用户名" onChange={this.handleChange.bind(this, 'name')} />
<input type="password" placeholder="请输入密码" onChange={this.handleChange.bind(this, 'password')} />
<GenderSelect handleSelect={this.handleSelect}></GenderSelect>
</form>
}
})
React.render(<SignupForm></SignupForm>, document.body);
三、Mixin混入
mixin允许我们定义多个组件中共用的方法。mixin目的是横向抽离出组件的相似代码
相似概念:面向切面编程、插件
var BindingMixin = {
handleChange: function(key) {
var that = this;
var newState = {};
return function(event) {
newState[key] = event.target.value;
that.setState(newState);
}
}
}
var BindingExample = React.createClass({
mixins: [BindingMixin],
getInitialState: function() {
return {
text: '',
}
},
render: function() {
return <div>
<input type="text" placeholder="请输入内容" onChange={this.handleChange('text')} />
<p>{this.state.text}</p>
</div>
}
})
React.render(<BindingExample></BindingExample>, document.body);
使用React编写的Mixin
<script src="./react-with-addons.js"></script>
//LinkedStateMixin,valueLink,linkState,
var BindingExample = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {
text: '',
comment: '',
}
},
render: function() {
return <div>
<input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} />
<textarea valueLink={this.linkState('comment')}></textarea>
<p>{this.state.text}</p>
<p>{this.state.comment}</p>
</div>
}
})
React.render(<BindingExample></BindingExample>, document.body);
使用mixin过程中其他注意事项建议参考《『译』React Mixin 的使用》:https://segmentfault.com/a/1190000003016446
参考链接
1、《浅入React。 一次》:http://www.wengwang.me/2015/12/02/qian-ru-react-ci-2/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
2、《『译』React Mixin 的使用》:https://segmentfault.com/a/1190000003016446