如题~~~
直接上干货!
逻辑与表示 分离
Logic 和 Presentation 分离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const Pig = ({weight, color, mature}) => ( <div> <p>weight: {weight}</p> <p>color: {color}</p> <p>mature: {mature}</p> </div> ) class PigContainer extends React.Components { constructor(props){ super(props); this.state = { weight: 100, color: 'white', mature: false, } } render(){ return <Pig {...this.state} /> } }
|
好处:单独测试数据与逻辑,如果设计稿要修改,只需要修改相应的显示组件
Mixins
在多个组件间分享同一种功能,mixin只能在React.createClass方法中使用,已经要废弃了,举个栗子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const windowResizeMixin { getInitialState() { return { innerWidth: window.innerWidth, } }, componentDidMount() { window.addEventListener('resize', this.handleResize) }, componentWillUnmount() { window.removeEventListener('resize', this.handleResize) }, handleResize() { this.setState({ innerWidth: window.innerWidth, }) } } const SomeCopmponent = React.createClass({ mixins: [windowResizeMixin], render() { console.log('window.innerWidth', this.state.innerWidth) ... }, })
|
可以看到Mixin其实还蛮好用的,但为什么要废气他呢,笔者认为这玩意破坏了组件里面的state的完整性,容易造成复写,另外有些mixin需要实现组件其中的某些方法才能生效,如果mixin多了,我们没有办法很快知道要实现哪些方法,很难管理,所以后来他们想到了更好的解决方案:高级组件
High-order Components
套路是这样的:
1
| const HoC = Component => EnhancedComponent
|
就是把组件作为参数传入函数,然后返回一个加强功能版的组件,就像把Steven放进锅炉炖一下就变成了美国队长~~~
把上面Mixin写成HoC后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| const withInnerWidth = Component => ( class extends React.Component { constructor(props){ super(props); this.state = { innerWidth: window.innerWidth } this.handleResize = this.handleResize.bind(this); } componentDidMount() { window.addEventListener('resize', this.handleResize) }, componentWillUnmount() { window.removeEventListener('resize', this.handleResize) }, handleResize() { this.setState({ innerWidth: window.innerWidth, }) } render(){ return <Component {...this.props} {...this.state} /> } } ) const SomeCopmponent = ({ innerWidth }) => { console.log('window.innerWidth', this.state.innerWidth); ... } const SomeCopmponentWithInnerWidth = withInnerWidth(SomeCopmponent); // toasted!
|
不要被这个栗子束缚了,所有的HoC都是函数,而且可以动态配置里面的传参,那么函数是可以嵌套的,有一个库Recompose用来处理嵌套的问题
Context
这里不得不提一下Context,这个属性虽然快要被废弃了,但是配上HoC,功能非常强大,可以在所有使用过该HoC的组件间共享状态。具体可以看react-redux是怎么实现的。
Function as Child!
套路是这样的:
1 2 3 4
| const FunctionAsChild = ({ children }) => children() FunctionAsChild.propTypes = { children: React.PropTypes.func.isRequired, }
|
那么这玩意能干嘛呢,举个栗子吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Fetch extends React.Component { constructor(props){ super(props); this.state = { data: []; } } componentDidMount() { ajax().then((res) => {this.setState({data: res})}) } render() { return this.props.childen(this.state.data); } } <Fetch url="..."> {data => <List data={data} />} </Fetch>
|
这个和HoC有什么区别呢?这个能动态绑定参数啊,url也许是动态变化的呢,HoC就懵逼了对不对=。=
好了,套路介绍到这里~