组件化
- 组件的封装
- 组件的复用
组件的封装
- 视图
- 数据
- 视图和数据之间的变化逻辑
import React, {Component} from 'react'; export default class List extends Component{ constructor(props){ super(props); this.state = { //数据 list:this.props.data, } } render() { return ( <div> <ul> {this.state.list.map(function(item,index){ return (<li key={index}>{item}</li>); })} </ul> </div> ) } }
组件的复用(通过props传递)
import React, {Component} from 'react'; import List from './list'; //组件 import Title from './title';//组件 export default class Todo extends Component{ constructor(props){ super(props); this.state = { list:['Foo','Bar'], } } todoList (item){ this.state.list.push(item); const newList=this.state.list; this.setState({ list:newList, }) } render() { return ( <div> <Title todoList={this.todoList.bind(this)} /> <List data={this.state.list}/> <Title todoList={this.todoList.bind(this)} /> //复用 <List data={[1,2,3]}/> //复用 </div> ) } }
JSX
React引入JSX,并将它作为了一个独立的标准开放,React.createElement也是可以自定义去修改的,
jsx语法(语法糖)需要转成js
ReactElement createElement( // 参数——标签属性子元素 string/ReactClass type, [object props], [children ...] )
npm i babel-cli -g
npm i --save-dev babel-plugin-transform-react-jsx
新建.babelrc文件,添加
{ "plugins": ["transform-react-jsx"] }
在项目根目录中运行babel --plugins transform-react-jsx src/components/todo/index.js
经过编译:转化成React.createElement,类似于vitual dom 的 h 函数
import React, { Component } from 'react'; import List from './list'; //组件 import Title from './title'; //组件 export default class Todo extends Component { constructor(props) { super(props); this.state = { list: ['Foo', 'Bar'] }; } todoList(item) { this.state.list.push(item); const newList = this.state.list; this.setState({ list: newList }); } render() { return React.createElement( 'div', //直接渲染 null, React.createElement(Title, { todoList: this.todoList.bind(this) }), //转化成React.createElement React.createElement(List, { data: this.state.list }), //List 是自定义构造函数,List 组件必须有render React.createElement(Title, { todoList: this.todoList.bind(this) }), React.createElement(List, { data: this.state.list }) ); } }
React.createElement(List, { data: this.state.list }), //List 是自定义构造函数,List 组件必须有render 相当于var list = new List({data: this.state.list}); var vNode = list.render(); //通过层层的render函数,最终React.createElement html标签
在文件开始添加 /* @jsx h */ 改变 React.createElement
/* @jsx h */ import React, { Component } from 'react'; import List from './list'; //组件 import Title from './title'; //组件 export default class Todo extends Component { constructor(props) { super(props); this.state = { list: ['Foo', 'Bar'] }; } todoList(item) { this.state.list.push(item); const newList = this.state.list; this.setState({ list: newList }); } render() { return h( 'div', null, h(Title, { todoList: this.todoList.bind(this) }), h(List, { data: this.state.list }), h(Title, { todoList: this.todoList.bind(this) }), h(List, { data: this.state.list }) ); } }
JSX中的VDom体现
jsx就是模版,最终需要转化成html,初次渲染,修改state后的setState 的re-render,正好适用于vDOM
ReactDOM.render(<App />, document.getElementById('root')); //初次渲染 <App /> JSX对象 //通过vDom的patch(container,vnode),而对于re-render是通过setState todoList (item){ this.state.list.push(item); const newList=this.state.list; this.setState({ //re-render patch(vnode,newVnode) list:newList, }) }
源码下载
该随笔相关代码已上传到github,地址:https://github.com/10086XIAOZHANG/ReactVisualDomDemo