首页 > 代码库 > React初探

React初探

经过几天根据官方文档和博园中一些大牛的文章,在了解过基础的语法和组件后,总结一下:

 

1.第一件事就是分析界面,理想状态下是让每个组件只做一件事情,也就是单一职责,相互嵌套。我认为:

  •  构建组件树,整体的构架,把整体的各个组件罗列出来。
  •  也可以从小组件开始写,能够清除的知道该组件需要什么数据,就让该组件的父组件只传所需要的数据。

 

2.我们要知道调用行第一次render方法的时候,声明周期到底执行了哪些方法?

初始化渲染:getDefaultProps

      getInitialState

      componentWillMount

      render

      componentDidMount

当然Props或者state改变:

      componentWillReceiveProps

      shouldComponentUpdata (数据发生改变返回ture执行render)

      componentWillUpdate

      render

      componentDidUpdata 

 

3.尝试了用es6+webpack 写todolist。 (参考了王福朋博客的todolist)

技术分享

class Text extends React.Component{
    
    constructor(){
        super(); 
        this.state={
            todolist:[]
        }
    }
    onchange(row){
        this.setState({
            todolist:row
        })
    }
    render(){
        
        return(
           <div>
               <TypeNew change={this.onchange.bind(this)} todolist={this.state.todolist}/>
               <ListTodo change={this.onchange.bind(this)} todolist={this.state.todolist}/>
           </div>
        )
    } 
}
  • 首先是最外层的组件,里面包括了TypeNew 输入框,ListType 展示列表。设置了初始状态值为空数组,onchange函数是改变数据时调用。
  • 往子组件传递方法和数据通过props。
  • 在es6 class语法中,change={this.onchange.bind(this)} 如果不写bind(this)将会找不到该方法,所以需要用bind()指定上下文。当然也可以在constructor()中设置。
class ListTodo extends React.Component{
    
    constructor(props){
        super(props);  
         
    }
    handleclick(e){
        var deIndex=e.target.getAttribute("data-index")
        this.props.todolist.splice(deIndex,1);
        this.props.change(this.props.todolist)
    }
    render(){
       
        return( 
          <ul>
            {
                this.props.todolist.map(function(item,index){
                    return <li className="list-border" key={index}>
                        <label>{item}</label>
                        <button data-index={index} onClick={this.handleclick.bind(this)}>delete</button>
                    </li>
                }.bind(this))
            }
          </ul>
        )
    } 
}
  • 通过this.props.todolist可以获取到由父组件传下来的数据。
  • 添加data-index自定义属性是为了获取点击后获取位置。 我们通过e.target 可以获取点击的元素,再通过getAttribute()获取自定义属性的值。再删除数组中对应位置的数据。
class TypeNew extends React.Component{
    
    constructor(props){
        super(props);  
        
    }
    onsubmit(e){
        e.preventDefault();
        var input=this.refs.myinput;
        var text=input.value;
        var row= this.props.todolist;
        if(text !==""){
            row.push(text)
            this.props.change(row)
            input.value=""
        }
        
    }
    render(){
        
        return( 
          <form onSubmit={this.onsubmit.bind(this)}>
                 <input ref="myinput" type="text" placeholder="typing a newthing todo"  />
         </form>
        )
    } 
}
  • 以上我们用从父组件传递下来的change函数通过传递参数的形式改变了父组件的数据。

 

4.尝试加入了react-router 路由功能。

看了阮一峰老师的react-router文章以及结合了一些实例,算是有所入门。

//main.js
import React from ‘react‘;
import ReactDom from ‘react-dom‘;

import Component1 from ‘./components/Component1.jsx‘;
import Text from ‘./components/Text.jsx‘;
import { Menu, Icon } from ‘antd‘;
import "antd/dist/antd.min.css" 

const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;

// 引入React-Router模块
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink} from ‘react-router‘
var i=0;
class App extends React.Component {
     constructor(){
        super();
       
    }
      
    render(){
        return (  
            <div>
            
              <div>
                    <Menu  mode="horizontal">
                      <Menu.Item key="mail">
                        <Icon type="mail" />Navigat ion One
                      </Menu.Item>
                      <Menu.Item key="app" >
                        <Icon type="appstore" />Navigation Two
                      </Menu.Item>
                      <SubMenu title={<span><Icon type="setting" />Navigation Three - Submenu</span>}>
                        <MenuItemGroup title="Item 1">
                          <Menu.Item key="setting:1"><IndexLink to="/" activeClassName=”active“ >Option 1</Link></Menu.Item>
                          <Menu.Item key="setting:2"><Link to="/Component1" activeStyle={{color: ‘red‘}} >Option 2</Link></Menu.Item>
                        </MenuItemGroup>
                        <MenuItemGroup title="Item 2">
                          <Menu.Item key="setting:3">Option 3</Menu.Item>
                          <Menu.Item key="setting:4">Option 4</Menu.Item>
                        </MenuItemGroup>
                      </SubMenu>
                      <Menu.Item key="alipay">
                        <a href="https://ant.design" target="_blank" rel="noopener noreferrer">Navigation Four - Link</a>
                      </Menu.Item>
                    </Menu>
              </div>
              <div>
               { this.props.children }
              </div>
            </div>
        )
    }
}

ReactDom.render(
     (
       <Router history={hashHistory}>
        <Route path="/" component={App}>   
            <IndexRoute    component={Text} />  
            <Route  path="Component1" component={Component1} /> 
        </Route>
      </Router>
     ),
     document.getElementById("content")
)

 

Router 本身就是一个容器  路由功能都需要它来定义。

hashHistory :表示页面的切换是通过url的hash的改变。

path : 参数定义了hash的值。

component :参数定义了访问的模块内容。

以上代码为嵌套路由,当我们访问localhost:8080时,首先会加载App组件(导航栏),无论如何切换页面,该导航栏都会存在。然后才会去加载它的子组件Text。至于为什么是Text?那得依靠IndexRoute 。

IndexRoute :参数表示默认加载的子组件,如果不写,该页面只会展示App组件,不会展示子组件。

嵌套路由时,App组件需要如代码标记处一样用this.props.childer。在切换页面时候将会在该位置展示子组件。

那该如何切换页面呢?Link组件。它取代了a标签,to参数指定了跳转路径,也即是path。该组件还可以添加activeStyle,activeClassName样式,当跳到该页面时 该标签也会改变样式。

 

就这么多了,任重而道远。

 

React初探