1.关于setState什么时候是同步什么时候是异步的问题
- setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。
- setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的 callback 拿到更新后的结果
- setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和 setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setState ,setState 的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新。
- libin1991.github.io/2017/09/21/…
2.展开运算符...
使用展开运算符可以实现数组复制,且复制后两者不受影响。
3.用React展示html代码——dangerousSetInnerHTML
4.扩展光标聚焦——label
5.父组件--子组件
【单向数据流】父组件可以向自组件传值,但子组件不能改变父组件的值
父组件向子组件传递数据,在父组件页面的子组件后面添加属性,在子组件页面通过{this.props.属性名}调用。
子组件中调用父组件的方法改变父组件的数据,注意this的指向做绑定
6.直接在构造函数里绑定this指针的指向
7.ES6函数中直接返回对象
8.???异步 变量外层保存
9.propTypes和defaultProps
propTypes:校验外部传入的属性的类型,可以是多种类型(如content),或规定其是否必须(如test)
defaultProps:设置传入属性的默认值
(使用前记得导入import PropTypes from 'prop-types';)
10.当组件的state或props发生变化时,render()函数就会重新执行;
当父组件的render()函数被运行时,子组件的render()函数都会被重新运行。 如果子组件在页面上直接使用父组件的属性,会获得同步更新。但如果子组件的state依赖于父组件,需要在componentWillReciveProps中手动setState进行子组件的state更新
11.虚拟DOM底层实现
- state数据
- JSX模版
- 数据+模版 生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真实DOM)(损耗性能)
eg:['div', {id: 'abc'},['span', {}, 'hello world']] - 用虚拟DOM的结构生成真实的DOM来显示
eg:<div><span>hello world</span></div> - state发生变化
- 数据+模版 生成新的虚拟DOM (极大提升来性能)
eg:['div', {id: 'abc'},['span', {}, 'bye bye']] - 比较原始虚拟DOM和新的虚拟DOM的区别,找去不同不分的内容
- 直接操作DOM,改变发生变化的内容
eg:return <div></span>item</span></div>
底层= JSX => createElement => 虚拟DOM(js对象)=> 真实DOM
return React.createElement('div', {}, React.create('span', {}, 'item'))
优点:
- 极大提升来性能
- 使得跨端应用得以实现。React Native
12.关于Diff算法
- 短间隔的多次setState可以结合成一次,减少虚拟DOM比对次数,优化性能
- 虚拟DOM比对时采用【同层比对】,从上至下,逐层比对。当发现有不同时,不再向下比对,直接废弃掉下层的虚拟DOM,直接用新的替换真实DOM
- 列表循环时引入key值,提高虚拟DOM比对的性能 。key值要保持稳定,尽量不要用index 做key值
13.
- arrayOf()表示输入的要求是数组,数组内容可以为number或者string
- oneOfType()表示输入的内容是number或者string,参数以数组的形式给出 \
14.ref——操作DOM,获取DOM元素
- e.target的结果是input对应的DOM元素节点\
- 不推荐使用ref,尽量不要直接操作DOM元素
15.生命周期函数
生命周期函数指某一时刻组件会自动调用执行的函数(如render()函数)
- Initialization
- constructor():设置props, state
- Mounting
- componentWillMount():组件即将被挂载(组件第一次在页面上展示)到页面之前被自动执行
- render():必须存在且自定义
- componentDidMount():组件被挂载到页面之后被自动执行
- Upnation (props, state)
- componentWillReceiveProps: (只针对props)一个组件要从父组件接收参数。只要父组件的render函数被重新执行了,子组件的这个生命周期函数就会被执行(该组件之前存在于父组件中,才会执行)。
- shouldComponentUpdate():组件被更新之前,被自动执行。该函数返回一个bool值,若返回false,组件不会更新;一般返回true,执行下面的更新流程。
- componentWillUpdate():组件被更新之前,它会自动执行。但是在shouldComponentUpdate()之后执行。若shouldComponentUpdate()返回false,它不会执行。
- render()
- componentDidUpdate:组件被更新之后,它会执行
- Unmounting
- componentWillUnmount():组件即将被从页面中移除时自动执行
16.性能优化
(其他性能优化方法:在constructor里进行函数的指针绑定;diff算法同层比较;setState函数异步,可以把多次数据更新合并成一次)
17.发送ajax请求
使用axios扩展工具,写在componentDidMount函数里
18.CSS实现
- 过渡效果
- 动画效果
forwards 表示保留变化后最后一帧的CSS样式
19.react-transition-group
在需要添加样式的标签外层嵌套<CSSTransiton></CSSTransition>
- in: 绑定参数,根据还参数的变换判断是出场(false)还是入场(true)
- timeout: 完成需要的时间
- classNames: css样式前缀
- unmountOnExit: 出场时删除对应DOM元素
- appear: 第一次载入页面时的样式(默认false。为true时,可以为其设置样式)
<TransitionGroup>组件管理列表中的一组<Transition>组件。<TransitionGroup>是一种状态机,用于管理组件随时间的安装和卸载。- 可以在
<TransitionGroup>中使用任何<Transition>组件,而不仅仅是css。 - 要把所有需要管理的列表项都写在
<TransitionGroup>中,其次,<CSSTranstion>组件的in属性此时由<TransitionGroup>管理了 - 当点击按钮后,将会把此项添加到列表中,此时in属性为true,同时默认设置了首次动画,所以会触发一次进场动画。
20.Redux工作流
21.流程实现
- 创建store
- 创建reducer
- 组件连接store,通过
this.state = store.getState();获得store中的数据
- 定义action,然后使用
store.dispatch(action);传递给store。store接受到后,自动将当前数据和接收到的action转发给reducer - reducer对数据进行处理,返回新数据给store
(reducer可以接收state,但绝不能修改state。
const newState = JSON.parse(JSON.stringify(state));深拷贝后对数据进行操作) - 组件更新。
store.subscribe(this.handleStoreChange);store内容发生改变时,自动调用作为参数的该函数 在该函数中,再次获取store的值即可 - 可用过定义action中的type值方便调试
- 可以创建一个actionCreate.js文件,存放所有action,在组件里直接调用即可
22.关于Redux
- store是唯一的
- 只有store能改变自己的内容
- Reducer必须是纯函数(纯函数:给定固定输入,一定有固定输出,并且不会有任何副作用)
23.组件
- 普通组件
- 容器组件:一般负责逻辑部分
- UI组件:一般负责页面渲染
- 无状态组件:如果一个组件只有render函数,可以将其写成无状态组件。无状态组件是一个函数,性能比普通组件高。
24.redux-thunk 中间件
store.dispatch(action);时会自动调用action的函数,该函数可以接收一个dispatch的参数,在函数体里直接dispatch(action)即可。
25.同时使用redux开发工具和redux-thunk中间件
import thunk from 'redux-thunk';
import reducer from './reducer.js'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(thunk),
);
const store = createStore(reducer, enhancer);
export default store;
26.redux-saga 中间件
- 在index.js中配置saga
import createSagaMiddleware from 'redux-saga';
import reducer from './reducer.js';
import todoSagas from './sagas.js';
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));
const store = createStore(reducer, enhancer);
sagaMiddleware.run(todoSagas);
export default store;
- 将异步请求代码写在sagas.js文件中
yield put(action);代替store.dispatch(action);