您的位置:首页 > 编程学习 > > 正文

react的setstate第二个参数(示例详解react中useState的用法)

更多 时间:2022-01-15 01:56:53 类别:编程学习 浏览量:254

react的setstate第二个参数

示例详解react中useState的用法useState

useState 通过在函数组件里调用它来给组件添加一些内部 state。React 会在重复渲染时保留这个 state。useState
会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的
this.setState,但是它不会把新的 state 和旧的 state 进行合并。

接下来通过一个示例来看看怎么使用 useState。

有这么一个需求:需要在 iframe 中加载外部网页

初始的代码我们通过 函数式组件 来实现这个需求,只需要简单的渲染一个 iframe

  • import React, { useState } from 'react';
    
    import styles from './index.less';
    
    function Link(props) {
      const { match: { params: { link = '' } = {} } = {} } = props;
      const enCodeUrl = decodeURIComponent(link);
      const url = enCodeUrl.startsWith('http') ? enCodeUrl : `http://${enCodeUrl}`;
      return (
        <React.Fragment>
            <iframe
              title={link}
              src={url}
              style={{ width: '100%', height: '100%', verticalAlign: 'top' }}
              frameBorder="0"
            />
        </React.Fragment>
      );
    }
    
    export default Link;
    
  • 新的需求来了,我们需要给页面添加一个 loading 效果,实现的方式很简单,监听 iframe 的 load 事件 来设置loading的开始和结束

    为了实现这个需求,我们需要存放loading的状态而函数式组件是没有自有状态的,我们得改造成 class 组件:

  • import React from 'react';
    import { Spin } from 'antd';
    
    import styles from './index.less';
    
    export default class Link extends React.Component {
      state = {
        // 存放loading状态
        iLoading: true,
      };
    
      linkLoad() {
        // 更新loading
        this.setState({ iLoading: false });
      }
    
      render() {
        const { match: { params: { link = '' } = {} } = {} } = this.props;
        const { iLoading } = this.state;
        const enCodeUrl = decodeURIComponent(link);
        const url = enCodeUrl.startsWith('http') ? enCodeUrl : `http://${enCodeUrl}`;
        return (
          <React.Fragment>
            <Spin spinning={iLoading} wrapperClassName={styles['iframe-loading']}>
              <iframe
                onLoad={this.linkLoad.bind(this)}
                title={link}
                src={url}
                style={{ width: '100%', height: '100%', verticalAlign: 'top' }}
                frameBorder="0"
              />
            </Spin>
          </React.Fragment>
        );
      }
    }
    
  • 为了实现一个页面的loading,我们需要去使用class,同时还需要bind绑定this等繁琐行为,这只是一个简单的需求,而我们却可以通过hooks来解决这些问题,同时还能解决组件间状态复用的问题,我们使用useState来实现

  • 导入 useState
    import React, { useState } from 'react';
    定义状态
      // useState 的参数为状态初始值,setInitLoading为变更状态值的方法
      const [initLoading, setInitLoading] = useState(true);
    更新状态
    onLoad={() => setInitLoading(false)}
    完整代码如下:
    
    import React, { useState } from 'react';
    import { Spin } from 'hzero-ui';
    
    import styles from './index.less';
    
    function Link(props) {
      const { match: { params: { link = '' } = {} } = {} } = props;
      const [initLoading, setInitLoading] = useState(true);
      const enCodeUrl = decodeURIComponent(link);
      const url = enCodeUrl.startsWith('http') ? enCodeUrl : `http://${enCodeUrl}`;
      return (
        <React.Fragment>
          <Spin spinning={initLoading} wrapperClassName={styles['iframe-loading']}>
            <iframe
              onLoad={() => setInitLoading(false)}
              title={link}
              src={url}
              style={{ width: '100%', height: '100%', verticalAlign: 'top' }}
              frameBorder="0"
            />
          </Spin>
        </React.Fragment>
      );
    }
    
    export default Link;
    
  • 下面看看useState注意事项

    useState 的参数

    useState 的参数可以是基本类型,也可以是对象类型,在更新对象类型时,切记要合并旧的状态,否则旧的状态会丢失

  • const [params, setParams] = useState({
      rotate: 0,
      color: "#000000"
    });
    
    const handleInputChange = event => {
      const target = event.target;
      setParams({
        ...params,
        [target.name]: target.value
      });
    };
    
  • 状态依赖

    如果当前的状态需要根据最后一次更新的状态的值计算出来,则给更新状态的函数传递一个函数,此函数的第一个参数即为最后一次更新的值,然后把计算后的结果做为返回值返回出去。

    总结

    利用 useState hook 可以让函数式组件拥有状态管理特性,它与传统的 class 组件的状态管理类似,但是更加简洁,不用频繁的使用 this。在后面的文章中将会介绍到如何结合其他的 hooks 对业务逻辑进行抽离以使组件代码和 hooks 代码各司其职。

    您可能感兴趣