React官方状态管理库—— Recoil

/*
 * @Descripttion: React官方状态管理库—— Recoil
 * @version: 
 * @Author: lhl
 * @Date: 2021-03-24 15:37:36
 * @LastEditors: lhl
 * @LastEditTime: 2021-03-24 16:59:52
 * @desc: 中文文档: https://www.recoiljs.cn/docs/introduction/installation
 * 安装: cnpm/npm install recoil  or  npm install recoil
 */
import React, { Component, Suspense } from 'react';
import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from 'recoil';

// 一个 atom 代表一个状态。Atom 可在任意组件中进行读写。读取 atom 值的组件隐式订阅了该 atom,
// 因此任何 atom 的更新都将导致订阅该 atom 的组件重新渲染
const textState = atom({
    key: 'textState', // unique ID (with respect to other atoms/selectors)
    default: '123', // default value (aka initial value)
});

// selector 代表一个派生状态,派生状态是状态的转换。可以将派生状态视为将状态传递给以某种方式修改给定状态的纯函数的输出
const countState = selector({
    key: 'countState', // unique ID (with respect to other atoms/selectors)
    get: ({get}) => {
      const text = get(textState);
      return text.length;
    },
});

// 错误捕获
class ErrorBoundary extends Component{
    constructor(props){
        super(props);
        this.state = {
            error: null, 
            errorInfo: null
        }
    }
    componentDidCatch(error,errorInfo){
        this.setState({
            error: error,
            errorInfo: errorInfo
        })
    }
    render(){
        if(this.state.errorInfo){
            // 错误页面
            return <h1>Something went wrong.</h1>
        }
        // 正常页面,渲染子组件
        return this.props.children;
    }
}

// 示例
function RecoilComp() {
  return (
    <RecoilRoot>
        <ErrorBoundary>
            <Suspense fallback={<div>Loading...</div>}>
                <Count/>
                <TextTest />
            </Suspense>
        </ErrorBoundary>
    </RecoilRoot>
  );
}

// useRecoilValue 与 useSetRecoilState 都可以获取数据,区别是 useRecoilState 还可以获取写数据的函数
// const [text, setText] = useRecoilValue(useRecoilState)
// useSetRecoilState 与 useRecoilState、useRecoilValue 的不同之处在于,数据流的变化不会导致组件 Rerender,因为 useSetRecoilState 仅写不读
// useResetRecoilState 重置到默认值并读取
// useRecoilCallback 通过回调方式定义要读取的数据,这个数据变化也不会导致当前组件重渲染
function Count() {
    const count = useRecoilValue(countState);
  
    return <>Count is: {count}</>
}

function TextTest() {
    const [text, setText] = useRecoilState(textState);
  
    const onChange = (event) => {
      setText(event.target.value);
    };
  
    return (
      <div>
        <input type="text" value={text} onChange={onChange} />
        <p>{text}</p>
      </div>
    );
}

export default RecoilComp

 未经允许,请勿随意转载!!谢谢合作!!!

posted @ 2021-03-26 18:55  鱼樱前端  阅读(656)  评论(0编辑  收藏  举报