Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Hook使用小记录 #49

Open
taikulawo opened this issue Oct 11, 2020 · 0 comments
Open

React Hook使用小记录 #49

taikulawo opened this issue Oct 11, 2020 · 0 comments
Labels

Comments

@taikulawo
Copy link
Collaborator

UseMemo 的使用

FP 组件每次更新渲染都会被调用,我们希望更新时保存上次渲染的状态
比如如下组件 onChange触发之后组件更新,结果输入的值又没了

const [formData, setFormData] = useState("");
const [formSchema, setFormSchema] = useState(defaultSchema);
return (
  <Row>
    <Col span={8}>
      <div className="pattern-editor">
        <Editor
          initialCode={JSON.stringify(defaultSchema)}
          onChange={() => {}}
        ></Editor>
      </div>
    </Col>
    <Col span={8}>
      <div className="WYSIWYG-editor">
        <SchemaForm
          schema={formSchema}
          onChange={(e) => {
            setFormData(JSON.stringify(e.formData));
          }}
        >
          <React.Fragment></React.Fragment>
        </SchemaForm>
      </div>
    </Col>
    <Col span={8}>
      <div className="config-output">
        <Editor
          initialCode={JSON.stringify(formData)}
          onChange={() => {}}
        ></Editor>
      </div>
    </Col>
  </Row>
);

而使用useMemo改造后,只要依赖数组不变化,那组件不会被重新渲染,状态还会被保留

const [formData, setFormData] = useState("");
const [formSchema, setFormSchema] = useState(defaultSchema);
return (
  <Row>
    <Col span={8}>
      <div className="pattern-editor">
        <Editor
          initialCode={JSON.stringify(defaultSchema)}
          onChange={() => {}}
        ></Editor>
      </div>
    </Col>
    <Col span={8}>
      <div className="WYSIWYG-editor">
        {useMemo(
          () => (
            <SchemaForm
              schema={formSchema}
              onChange={(e) => {
                setFormData(JSON.stringify(e.formData));
              }}
            >
              <React.Fragment></React.Fragment>
            </SchemaForm>
          ),
          [formSchema]
        )}
      </div>
    </Col>
    <Col span={8}>
      <div className="config-output">
        {useMemo(
          () => (
            <Editor
              initialCode={JSON.stringify(formData)}
              onChange={() => {}}
            ></Editor>
          ),
          [formData]
        )}
      </div>
    </Col>
  </Row>
);

useRef

函数组件每次调用函数都是新的引用,如果这个函数你传给了子组件,子组件不重新渲染那拿不到最新的函数,可以利用useRef保存函数状态

image

useEffect

最佳实践

看下面的代码,我们希望 createItem 创建完刷新页面,拉取最新的数据。

 const [pattern, setPattern] = useState({});
useEffect(() => {
    (async () => {
        const items_temp = await api.items.getAllItems(key_id);
        const key_temp = await api.keys.getOne(key_id);
        setItems(items_temp);
        setKey(key_temp);
    })();
}, []);

如果我们将API请求和 setXXX 放到 componentDidUpdate 里会触发React无限更新

const [x, SetX] = useState([]);
useEffect(() => {
    (async () => {
        const x = await api.get(id);
        // 这样会触发无限更新!
        setX(x);
    })();
})

解决办法是把API和SetX做成单独的函数,不要放到 useEffect 里,需要的时候调用一下就好了

useEffect(() => {
    (async () => {
        fetchList();
    })();
}, []);
async function fetchList() {
    const items_temp = await api.items.getAllItems(key_id);
    const key_temp = await api.keys.getOne(key_id);
    setItems(items_temp);
    setKey(key_temp);
}

需要的拉取新数据时就调用一下

try {
    await api.items.createItem(key_id, {
        Value: value,
        ...toUpperCase(data)
    });
} catch (e) {
    console.log(e);
} finally {
    setLoading(false);
    setModalVisiable(false);
    fetchList();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant