author: 轩邈javascript
eg: const [count, setCount] = useState(0)html
介绍java
(1)有一个参数:默认值, 能够是函数,只在初始渲染时执行一次node
(2)返回一个带有两个元素的数组react
(3)第一个元素是 state 的值, 第二个元素是更新state的函数,每次新的,使用useCallback,可让它使用上次的函数;函数名随意不必定是set某某某,参数能够是要更新的值或者函数,当是函数时,函数参数是上一次state的值。git
(4) 若是有多个state则根据 useState 的调用顺序来“记住”每一个state的状态归属
(5)这个特性要求Hooks不能够写在if或者switch等可能不执行的代码片断,会致使调用次序不一致
复制代码
签名与 useEffect 相同,在DOM变化(layout布局)后同步触发,渲染之前(paint绘制)执行 ,适用于用户可见的 DOM 改变。github
与 componentDidMount
和 componentDidUpdate
不一样,传递给 useEffect
的函数在DOM变化(layout布局) 和渲染(paint绘制)后触发。 这使得它适用于许多常见的 side effects ,例如设置订阅和事件处理程序,由于大多数类型的工做不该阻止浏览器更新(判断标准)屏幕。redux
`componentDidMount: useLayoutEffect(() => {setTitle(1)}, [])`
`componentDidUpdate: useLayoutEffect(() => {console.log(1)})`
`componentWillUnmount: useLayoutEffect()=>{return () => {console.log('我要卸载组件啦')}}`
我是一个方法,组件更新后返回,下次组件更新前执行:`useLayoutEffect(() => {return () => {console.log(‘我是一个方法,组件更新后返回,下次组件更新前执行')}}, [count, count2])`
复制代码
1. 第一个为函数,默认会在渲染完成后执行一次,若是返回的是一个函数,则返回的函数会在第二个参数数组里面的元素发生变化且渲染完成后执行
2. 第二个为一个数组(也能够写成常量等类型,不过不会调用参数一),里面写须要监控的state,当state改变时会调用第一个函数,不改变则不会调用参数一,当数组为空时,只会在最开始调用一次,至关于componentDidMount;不传时,默认监控全部state,至关于componentDidUpdate
复制代码
const theme = useContext(ThemeContext)
复制代码
```javascript
const ThemeContext = React.createContext();
const LanguageContext = React.createContext();
```
```js
<ThemeContext.Consumer>
{
theme => (
<LanguageContext.Cosumer>
language => {
//可使用theme和lanugage了
}
</LanguageContext.Cosumer>
)
}
</ThemeContext.Consumer>
```
两个render props写法,两个嵌套看起来麻烦不少
使用useContext时
```js
const theme = useContext(ThemeContext);
const language = useContext(LanguageContext);
// 这里就能够用theme和language了
```
接受一个由React.createContext返回的上下文对象,写法简化不少而且再也不须要理解render props
复制代码
```javascript
const ThemedPage = () => {
const theme = useContext(ThemeContext);
return (
<div>
<Header color={theme.color} />
<Content color={theme.color}/>
<Footer color={theme.color}/>
</div>
);
};
```
当theme的其余属性(如size等其余非color属性)改变时也会致使界面从新渲染
复制代码
```javascript
const initialState = { count: 0 }
const reducer = function reducer(state, action) {
switch (action.type) {
case 'reset':
return initialState
case 'increment':
return { ...state, count: state.count + 1 }
case 'decrement':
return { ...state, count: state.count - 1 }
default:
return state
}
}
```
//上面这部分应该写在函数组件外面防止函数一遍遍的建立
const [count3, count3Dispatch] = useReducer(reducer, initialState)
复制代码
```javascript
const [count4, setCount4] = useState(0)
const counterRef = useRef(count4)
useEffect(
() => {
counterRef.current = count4
},
[count4]
)
const incrementCount4 = useCallback(() => setCount4(counterRef.current + 1), [])
```
复制代码
介绍:useCallback(fn, inputs) 等价于 useMemo(() => fn, inputs)小程序
介绍:useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数(initialValue)。返回的对象将存留在整个组件的生命周期中。react-native
```javascript
// eg:
const useMountLog = name => {
useEffect(() => {
console.log(`${this.name}组件渲染时间->${this.end - this.begin}ms`)
},[])
}
```
复制代码
// eg: usePrevious
function usePrevious(value) {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}
复制代码
packages/shared
目录下全部文件中的enableHooks = false
替换为enableHooks = true
yarn install
yarn build -- --type=RN_OSS
build/react-native/
下的内容替换 项目路径/node_modules/react-native/Libraries/Renderer
(我使用时react-native版本为0.57.8)下的内容替换类组件
// 改造前
export default class HomeScene extends Component{...}
// 改造后
export default forwardRef((props, ref) => {...}) // forwardRef包起来是方便函数组件内部方法调用
复制代码
构造函数移除
state状态修改和建立改成useState const [visible, setVisible] = useState(false)
改造前父组件经过ref引用子组件的方法,改造后使用forwardRef
将createRef建立的ref传递到子组件内部,再使用useImperativeMethods将内部方法绑定到传进来的ref上
useImperativeMethods(ref, () => ({ showModal: this.showModal }), [])
复制代码
方法
// 改造前
showModal = (from, data, ticket) => {...}
// 改造后
this.showModal = (from, data, ticket) => {...} // 推荐使用箭头函数方便函数间调用
复制代码
render改成return,按state状态变化将原先render前的逻辑移入对应useEffect。
(1)引入StoreContext将根组件包起来
<StoreContext.Provider value={store}>
...
</StoreContext.Provider>
复制代码
(2)```javascript // 改造前 const { name, cityName } = this.props.UserInfo // 改造后 const mapState = React.useCallback(state => state.UserInfo, []) const { name, cityName } = useMappedState(mapState)
(3)每次调用useMappedState都会执行subscribe store。 可是,若是store更新,你的组件将只从新渲染一次。 所以,屡次调用useMappedState(例如封装在自定义hooks中)不该该对性能产生很大影响。 若是测试发现性能影响较大,能够尝试返回对象。
复制代码
引入react-navigation-hooks,需升级react-navigation至最新版(3.1.0)适配。
(1)使用
```javaScript
const { navigate } = useNavigation()
```
与原先的路由管理共用一套路由
复制代码
(2)注意:
1) 若是项目是用pod管理,该RNGestureHandler.podspec里面路径有问题须要修改。
2) createBottomTabNavigator的第二个参数BottomTabNavigatorConfig的navigationOptions属性改成了defaultNavigationOptions
复制代码
target.$$typeof === Symbol.for('react.forward_ref')
(我暂时是这样处理的)useCallback
包裹,并传一个空数组,来保证永远只监听一次,并且不须要在组件销毁时注销这个 callback。原文连接: tech.meicai.cn/detail/81, 也可微信搜索小程序「美菜产品技术团队」,干货满满且每周更新,想学习技术的你不要错过哦。