div id =‘root‘ / div script src ="./react.js" / script script src ="./react-dom.js" / script script src ="./babel.min.js" / script script type ="text/babel" class App extends React.Component{ render(){ return ( div h1 组件内标题 /
<div id=‘root‘></div> <script src="./react.js"></script> <script src="./react-dom.js"></script> <script src="./babel.min.js"></script> <script type="text/babel"> class App extends React.Component{ render(){ return( <div> <h1>组件内标题</h1> <p>组件内段落</p> {/*this.props.children代表组件使用时已有的内容*/} {this.props.children} </div> ) } } ReactDOM.render(<App><h3>组件外的你内容...</h3><section>组件外的section</section></App>,document.getElementById(‘root‘)) //这时候h3里的内容是无法显示的 被上面的div替换了 vue里要保留是用slot 要把h3和section分散渲染进去 vue使用slot命名 //react里用this.props.children 会把h3和section一起渲染进去 没法分散渲染 </script>
02-组件包含
<div id=‘root‘></div> <script src="./react.js"></script> <script src="./react-dom.js"></script> <script src="./babel.min.js"></script> <script type="text/babel"> class App extends React.Component{ render(){ return( <div> {this.props.first} <h1>组件内标题</h1> <p>组件内段落</p> {/*this.props.children代表组件使用时已有的内容 children是默认属性 代表组件内的子节点 children只收所有的节点 想分开放就自己定义属性 属性内容是可以随意什么的 也可以放标签 例如: first={<h3>组件外的内容...</h3> */} {this.props.children} {this.props.last} </div> ) } //class Child extends App 没有这种说法 子组件继承父组件 React里只有包含关系 继承关系就是包含关系 } ReactDOM.render(<App first={<h3>组件外的内容...</h3>} last={<section>组件外的section</section>}><figure>默认的内容...</figure></App>,document.getElementById(‘root‘)) //这时候h3里的内容是无法显示的 被上面的div替换了 vue里要保留是用slot //react里用this.props.children </script>
03-组件混合
<div id=‘root‘></div> <script src="./react.js"></script> <script src="./react-dom.js"></script> <script src="./babel.min.js"></script> <script type="text/babel"> //MyComponent1和MyComponent2有两个函数都是一样的 没必要重复写 怎么复用? //React.Component没有mixins 只有React.createClass有 //定义混合对象 const myMixins={ componentWillMount() { console.log(‘component will mount..‘) }, show() { console.log(‘show....‘) }, } const MyComponent1= React.createClass({ mixins:[myMixins], componentWillMount(){ console.log(‘组件1即将挂载....‘) },//组件1两个生命周期函数都调用了 先调用了mixins的 然后又调用自身的 //但对于普通函数,例如show,调用2次就会报错 render(){ return( <div> 组件1 </div> ) } }) const MyComponent2= React.createClass({ mixins:[myMixins],//将混合对象混合到当前组件 // show(){ // console.log(‘show....‘) // }, render(){ return( <div> 组件2....<button onClick={this.show}>show</button> </div> ) } }) ReactDOM.render(<div><MyComponent1 /><h2/><MyComponent2 /></div>,document.getElementById(‘root‘)) //componentWillMount已进入就被调用2次 说明mixins混入了 但能不能复写show函数呢? //就因为这原因,mixins被废弃了 </script>
04-高阶组件
<div id=‘root‘></div> <script src="./react.js"></script> <script src="./react-dom.js"></script> <script src="./babel.min.js"></script> <script type="text/babel"> //高阶组件就是一个函数,且该函数接收一个组件作为参数,并返回一个新的组件。参数是组件,返回值是新组件 //定义高阶组件 //WrapedComponent是包裹组件就是传进去的组件,然后要传出来一个新的组件 出来的组件就包含了新的方法之类的 function withSubCom(WrapedComponent) { //return一个新组件 除了少一个名字之外,它是一个组件定义 return class extends React.Component{ //这里面可定要把公共的东西定义好,特有的交给传进来的包裹组件 //公共的部分,此时新组建(class extends React.Component)和包裹组件是父子关系 子组件可以通过props接收参数 例如:onClick={this.props.show} componentWillMount() { console.log(‘component will mount..‘) } show() { console.log(‘show....‘) } render(){ return( <WrapedComponent show={this.show}/> ) } } } class MyComponent1 extends React.Component{ //现在这个组件不是我们期望的完整的组件 因为缺少show函数 componentWillMount(){ console.log(‘组件1即将挂载....‘) } render(){ return( <div > {/*能调用到公共的show*/} 组件1<button onClick={this.props.show}>show</button> </div> ) } } class MyComponent2 extends React.Component{ //要调用自定义的show 此时onClick的show调用就不用写成this.props.show 写成this.show就是调用自己的show //利用包含思想 解决组件的重用 show=()=>{ console.log(‘组件2的show...‘) } render(){ return( <div> 组件2....<button onClick={this.show}>show</button> </div> ) } } //变成我们期望的组件 下面就变成我们期望的组件 const EnhanceComponent1=withSubCom(MyComponent1) const EnhanceComponent2=withSubCom(MyComponent2) ReactDOM.render(<div><EnhanceComponent1 /><h2/><EnhanceComponent2 /></div>,document.getElementById(‘root‘)) </script> 高阶组件总结:<br/> 高阶组件是一个普通函数,可以接收任何参数,能够接收一个组件并返回一个新的组件<br/> 高阶组件模式允许我们在一个地方定义逻辑并且能对所有的组件使用<br/> 高阶组件是通过将原组件 包裹(wrapping)在容器组件(container component)里面的方式来组合(composes)使用原组件<br/> 高阶组件不会修改被包裹组件,高阶组件通过props将数据和方法告知给子组件,除了给被包裹组件传递容器组件新增的数据外,还要将容器组件已有的props传递给被包裹的组件<br/> 通过props可以将容器组件的state.props.event等都传递给被包裹组件,但不能传毒ref属性<br/> 不要在render函数中调用高阶组件,这样会是的每次得到的容器组件都是一个新组件,重新加载一个组件会引起原有组件的所有状态和子组件丢失,并且性能非常差<br/> 被包裹组件被容器组件包裹,也就意味着新组件(容器组件)会丢失原始组件(被包裹组件)的所有静态方法,因此必须将被包裹组件的静态方法拷贝到容器组件上,如果有静态方法