React技术栈-组件组合使用实战案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.功能界面的组件化编码流程
拆分组件:
拆分界面,抽取组件
实现静态组件:
使用组件实现静态页面效果,没有动态数据和交互。
实现动态组件 实现动态显示初始化数据 实现交互功能(从绑定事件监听开始)
二.实战案例
1>.HTML源代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>组件组合使用</title> </head> <body> <div id="box1"></div> </body> <script type="text/javascript" src="../js/react.development.js"></script> <script type="text/javascript" src="../js/react-dom.development.js"></script> <script type="text/javascript" src="../js/prop-types.js"></script> <script type="text/javascript" src="../js/babel.min.js"></script> <script type="text/babel"> /** * 问题1:数据保存在哪个组件内? * 看数据是某个组件需要(给它),还是某些组件需要(给共同的父组件) * * 问题2:需要在子组件中改变父组件的状态 * 子组件中不能直接改变父组件的状态,状态在哪个组件,更新状态的行为(函数)就应该定义在哪个组件 * 解决方案:父组件定义函数,传递给子组件,子组件调用 */ //1>.定义组件 class MyApp extends React.Component{ constructor(props){ super(props); //初始化状态 this.state = { myAppTodos:["抽烟","喝酒","斗地主"] } //绑定this(当前组件) this.addTodo = this.addTodo.bind(this) } addTodo(todo){ //this.state.todos.unshift(todo) //不能这么做,应该按照下面的方法更新 const {myAppTodos} = this.state myAppTodos.unshift(todo) //更新状态 this.setState({myAppTodos}) } render(){ //解构赋值,为了下面调用方便 const {myAppTodos} = this.state return ( <div> <h1>Simple TODO List</h1> <MyAdd count={myAppTodos.length} addTodo={this.addTodo}/> <MyList todos={myAppTodos}/> </div> ) } } class MyAdd extends React.Component{ constructor(props){ super(props); this.add = this.add.bind(this); } add(){ //1>.读取输入的数据 const todo = this.todoInput.value.trim(); //2>.检查输入的合法性 if (!todo){ return; } //3>.添加数据 this.props.addTodo(todo); //4>.清除输入 this.todoInput.value = ""; } render(){ return ( <div > <input type="text" ref={input => this.todoInput = input}/> <button onClick={this.add}>add ${this.props.count + 1}</button> </div> ) } } //声明MyList这个组件必须有count和addTodo属性(props) MyAdd.propTypes = { count:PropTypes.number.isRequired, addTodo:PropTypes.func.isRequired } class MyList extends React.Component{ //初始化显示动态数据 render(){ //解构赋值,为了下面调用方便 const {todos} = this.props return ( <div> <ul> { todos.map((todo,index) => <li key={index}>{todo}</li> ) } </ul> </div> ) } } //声明MyList这个组件必须有一个todos属性(props) MyList.propTypes = { todos:PropTypes.array.isRequired } //2>.渲染组件标签 ReactDOM.render(<MyApp />,document.getElementById("box1")) </script> </html>
2>.浏览器打开以上代码渲染结果
打开页面如上图所示,我们可以添加数据,当数据添加成功后会打印在当前列表页面,如下图所示。