React相关React是一个声明式、高效且灵活的用户界面构建框架。JSX本质上,JSX只是React.createElement(component,props,...children)方法的语法糖。例如下面的代码:constelement=(Hello,world!);编译为:constelement=React.createElement('h1',{className:'greeting'},'Hello,world!');React.createElement()这个方法会先进行一些检查以避免bug,然后返回一个类似下面例子的对象:constelement={type:'h1',props:{className:'greeting',children:'Hello,世界'}};此类对象称为React元素,它们代表您在屏幕上看到的所有内容。我们在使用React开发应用时,一般只定义一个根节点。为了将React元素渲染到根DOM节点中,我们通过将它们都传递给ReactDOM.render()方法来在页面上渲染它们:ReactDOM.render(element,document.getElementById('root'));per当一个React元素发生变化时,ReactDOM首先比较元素的内容,然后操作浏览器DOM更新变化的部分。组件和道具当React遇到一个用户定义的组件元素时,它会将JSX属性作为称为道具的单个对象传递给组件。无论组件是使用函数还是类声明的,它都不能修改自己的props。比如这段代码会在页面上渲染Hello,Sara://使用ES6类定义一个组件,组件名必须以大写字母开头。classWelcomeextendsReact.Component{render(){return
Hello,{this.props.name}
;}}constelement=
;ReactDOM.render(element,document.getElementById('root'));让我们回顾一下这个例子中发生了什么:我们在元素上调用了ReactDOM.render()方法。React将{name:'Sara'}作为props传递并调用Welcome组件。Welcome组件返回一个Hello,Sara
元素作为结果。ReactDOM将DOM更新为Hello,Sara
。State&LifecycleComponents通过props获取属性,不可修改;当我们需要修改当前组件的状态时,需要使用state来设置局部状态,需要通过this.setState()来更新组件的局部状态:classToggleextendsReact.Component{constructor(道具){超级(道具);//初始化this,并赋值this.propsthis.state={isToggleOn:true};//初始化this.statethis.handleClick=this.handleClick.bind(this);//为this.handleClick绑定这个对象}handleClick(){this.setState(prevState=>({isToggleOn:!prevState.isToggleOn}));//使用this.setState()更新this.state}render(){return({this.state.isToggleOn?'ON':'OFF'});}}ReactDOM.render(,document.getElementById('root'));每个组件都有几个“生命周期方法”,您可以覆盖这些方法,让代码在处理过程中的特定时间运行。以will为前缀的方法将在特定链接之前被调用,而以did为前缀的方法将在特定链接之后被调用。Assembly:创建组件实例并将其插入DOM时调用这些方法:-constructor(`props`)-componentWillMount()-render()-componentDidMount()更新:属性或状态的更改会触发更新。当一个组件被重新渲染时,这些方法将被调用:-componentWillReceiveProps(`nextProps`)-shouldComponentUpdate(`nextProps`,`nextState`)-componentWillUpdate(`nextProps`,`nextState`)-render()-componentDidUpdate(`prevProps`,`prevState`)Unmount:当一个组件从DOM中移除时,这个方法被调用:-componentWillUnmount()当项目视图交互复杂频繁时,会出现状态仍然用于state变化极其繁琐且不可预测。这时候就需要借助Redux框架,将所有的状态数据都交给Redux进行处理,而React单独负责视图的展示,这样会使项目逻辑简单明了。Redux相关的三个原则:整个应用的状态存储在一个对象树中,这个对象树只存在于唯一的store中。改变状态的唯一方法是触发动作,动作是用来描述事件的普通对象。要描述操作如何改变状态树,您需要编写reducer。ActionAction是将数据从项目传递到商店的有效负载。它是商店数据的唯一来源。通常您通过store.dispatch()将操作传递给商店。Action本质上是一个普通的JavaScript对象。添加新todo任务的action如下所示:{type:'ADD_TODO',text:'BuildmyfirstReduxapp'}Action创建函数是生成action的方法。Redux中的动作创建者只需返回一个action:functionaddTodo(text){return{type:'ADD_TODO',text:text}}这样做将使动作创建者更容易移植和测试。只需将动作创建函数的结果传递给dispatch()方法即可启动调度过程。dispatch(addTodo(text));//或者创建一个绑定动作创建函数来自动调度:constboundAddTodo=(text)=>dispatch(addTodo(text));boundAddTodo(文本);可以在store中直接通过store.dispatch()调用dispatch()方法,但大多数情况下你会使用react-redux提供的connect()helper。ReducerAction只是描述了某事发生的事实,而reducer所做的是指定应用程序应如何更新状态。reducer是一个纯函数,它接收旧状态和操作并返回新状态。(previousState,action)=>newState保持reducer的纯净非常重要。千万不要在reducer中做这些操作:修改传入的参数;执行有副作用的操作,例如API请求和路由跳转;调用不纯函数,例如Date.now()或Math.random()。我们将从指定状态的初始状态开始。第一次执行Redux时,状态是未定义的。这时候我们可以趁机设置并返回应用的初始状态:constinitialState={};//初始化statefunctiontodoApp(state=initialState,action){switch(action.type){case'ADD_TODO':returnObject.assign({},state,{text:action.text})default:returnstate//返回到默认情况下的旧状态}}每个reducer只负责管理它负责的部分全局状态。每个reducer的state参数是不同的,对应于它管理的那部分状态数据。combineReducers()做的是生成一个调用你的一系列reducer的函数,每个reducer根据自己的key过滤掉state中的一部分数据进行处理,然后生成的函数将所有reducer的结果合并成一个大物体。从'redux'导入{combineReducers};consttodoApp=combineReducers({visibilityFilter,todos})exportdefaulttodoApp;请注意,上面的内容完全等同于以下内容:接收一个对象,可以将所有顶层reducer放到一个单独的文件中,通过export暴露每个reducer的函数,然后使用import*asreducers获取一个对象,以他们的名字为keys:import{combineReducers}from'redux'import*asreducersfrom'./reducers'consttodoApp=combineReducers(reducers)Storeaction描述了发生了什么,reducers根据action来更新状态,Store是将它们联系在一起的对象。Store有以下职责:维护应用程序的状态;提供getState()方法获取状态;提供dispatch(action)方法来更新状态;通过subscribe(listener)注册监听器;通过subscribe(listener)返回的函数取消监听。我们使用combineReducers()将多个reducer合并为一个。现在我们导入它并传递createStore()。import{createStore}from'redux'importtodoAppfrom'./reducers'letstore=createStore(todoApp)createStore()的第二个参数是可选的,用于设置状态的初始状态。这在开发同构应用程序时非常有用。服务端redux应用的状态结构可以和客户端保持一致,这样客户端可以直接使用从网络接收到的服务端状态进行本地数据初始化。letstore=createStore(todoApp,window.STATE_FROM_SERVER);数据流Redux应用程序中数据的生命周期遵循以下4个步骤:调用store.dispatch(action)。Reduxstore调用传入的reducer函数。rootreducer应该将多个子reducer的输出组合成一个状态树。Reduxstore保存了根reducer返回的完整状态树。Router直接使用集成的react-router-redux,后面会详细讲。具体使用的话,就模仿官方的案例,官方文档。ContainerComponents和PresentationComponentsRedux的Reactbinding库包含了容器组件和Presentation组件分离的开发思想。只在最顶层的组件(例如路由操作)中使用Redux是明智的。其余内部组件仅用于展示,所有数据均通过props传入。系列目录前端统一时代要来了?React项目实战:环境搭建React项目实战:react-redux-router基本原理React项目实战:登录页面(编辑中)