最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • react浅析

    正文概述 掘金(WILL)   2021-04-08   559

    1. react 16 版本生命周期有哪些?

    • 初始化阶段
      • constructor 构造函数
      • getDefaultProps props 默认值
      • getDefaultState state 默认值
    • 挂载阶段
      • componentDidMount 组件已经被渲染到 DOM 中 (对应 mounted)
      • render
    • 更新阶段
      • shouldComponentUpdate
      • componentDidUpdate
    • 卸载阶段
      • componentWillUnmount (对应 destoryed)
    • 错误处理
      • componentDidCatch

    2. props 和 state 的区别?

    • props 是外部传入的数据参数, 不可变;
    • state 是组件内部的状态, 可变;
    • 没有 state 的是无状态组件, 有 state 的是有状态组件;
    • 多用 props, 少用 state, 即多写无状态组件

    3. setState 是同步的还是异步的?

    • 结论: 原生事件, setTimeOut 是同步的, 合成事件, 生命周期中是异步的

    • 异步示例

        componentDidMound(){
          this.setState({index: this.state.index + 1});
          console.log(index)
        }
    
    • 同步示例
        componentDidMound(){
          setTimeout(()=>{
            console.log(this.state.index)
            this.setState({index: this.state.index + 1});
            console.log(this.state.index)
          })
        }
    

    4. react hook

    • 基础示例:
      import React, { useState } from "react";
        function Example() {
          const [count, setCount] = useState(0);
          return (
            <div>
              <p>点击{{ count }}次</p>
              <button onClick={() => setCount(count + 1)}></button>
            </div>
          );
        }
    
    • Hook 声明多个 state 变量
      function Example() {
      const [count, setCount] = useState(0);
      const [name, setName] = useState("xiaoming");
      }
    
    • Effect Hook
      • 副作用: 如果在 react 组件中, 执行数据获取, 订阅或手动修改 DOM, 统一叫做副作用
      • useEffect 钩子, 给函数组件增加了操作副作用的能力, 它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API
        // 示例:
        import React, { useState } from "react";
        function Example() {
          const [count, setCount] = useState(0);
          useEffect(() => {
            document.title = `点击了${count}次`; // 完成对DOM的更改后执行useEffect中的代码
          });
          return (
            <div>
              <p>点击{count}次</p>
              <button onClick={() => setCount(count + 1)}></button>
            </div>
          );
        }
    
    清除副作用: 副作用函数可以通过返回一个函数来清除副作用.
    
        // 下面的组件使用副作用来订阅好友的在线状态, 并通过取消订阅来清除操作;
        import React, { useState, useEffect } from "react";
    
        function FriendStatus(props) {
          const [isOnline, setIsOnline] = useState(null);
    
          function handleStatusChange(status) {
            setIsOnline(status.isOnline);
          }
    
          useEffect(() => {
            ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
            return () => {
              ChatAPI.unsubscribeFromFriendStatus(
                props.friend.id,
                handleStatusChange
              );
            };
          });
    
          if (isOnline === null) {
            return "Loading...";
          }
          return isOnline ? "Online" : "Offline";
        }
    
    • 自定义 hook
      • 如果在组件之间有一些重用的状态逻辑, 有两种主流方案可以解决, 高阶组件和 render props, 自定义 hook 可以让你在不增加组件的情况下实现
        // 自定义hook示例:
        function useFriendStatus(friendID) {
          const [isOnline, setIsOnline] = useState(null);
    
          function handleStatusChange(status) {
            setIsOnline(status.isOnline);
          }
    
          useEffect(() => {
            ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
            return () => {
              ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
            };
          });
          return isOnline;
        }
        // 以friendID为参数, 并返回该好友是否在线
        // 在以下两个组件中使用
        function findFriendStatus(props) {
          const isOnline = useFriendStatus(props.friend.ID);
          if (isOnline === null) {
            return "Loading...";
          }
          return isOnline ? "Online" : "Offline";
        }
    
        function FriendListItem(props) {
          const isOnline = useFriendStatus(props.friend.id);
    
          return (
            <li style={{ color: isOnline ? "green" : "black" }}>
              {props.friend.name}
            </li>
          );
        }
    

    可以在自定义 hook 中传递数据

        function transData() {
          const [id, setId] = useState(0);
          const isOnline = findFriendStatus(id);
        }
    
    • hook 规则

        1. 不要在循环, 条件或嵌套函数中调用 hook, 确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们. 遵循这条规则, 可以保证每一次渲染都按照同样的顺序被调用, 这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确
        // 示例:
            function Form() {
         // 1. Use the name state variable
         const [name, setName] = useState("Mary");
        
         // 2. Use an effect for persisting the form
         useEffect(function persistForm() {
           localStorage.setItem("formData", name);
         });
        
         // 3. Use the surname state variable
         const [surname, setSurname] = useState("Poppins");
        
         // 4. Use an effect for updating the title
         useEffect(function updateTitle() {
           document.title = name + " " + surname;
         });
        
         // ...
        }
        
        1. 只能在 react 函数中调用 hook

    5. 高阶组件

      // 示例:
        const commentList = withSubscription(CommentList, DataSource =>
          DataSource.getComment()
        );
    
        const BlogPost = withSubscription(BlogPost, (DataSource, props) => {
          DataSource.getBlogPost(props.id);
        });
    
        function withSubscription(WrappedComponents, selectedData) {
          return class extends React.components {
            constructor(props) {
              super(props);
              this.handleChange = this.handleChange.bind(this);
              this.state = {
                data: selectedData(DataSource, props)
              };
            }
            componentDidMount() {
              // ...负责订阅相关的操作...
              DataSource.addChangeListener(this.handleChange);
            }
    
            componentWillUnmount() {
              DataSource.removeChangeListener(this.handleChange);
            }
    
            handleChange() {
              this.setState({
                data: selectData(DataSource, this.props)
              });
            }
            render() {
              return <WrappedComponents data={this.state.data} {...this.props} />;
            }
          };
        }
    

    6. render props

        //  示例1:
        <DataProvider render={data => <h1>{data.target}</h1>} />;
    
        // 示例2
        class Cat extends React.Component {
          render() {
            const mouse = this.props.mouse;
            return (
              <img
                src="/cat.jpg"
                style={{ position: "absolute", left: mouse.x, top: mouse.y }}
              />
            );
          }
        }
    
        class Mouse extends React.Component {
          constructor(props) {
            super(props);
            this.handleMouseMove = this.handleMouseMove.bind(this);
            this.state = { x: 0, y: 0 };
          }
    
          handleMouseMove(event) {
            this.setState({
              x: event.clientX,
              y: event.clientY
            });
          }
    
          render() {
            return (
              <div style={{ height: "100vh" }} onMouseMove={this.handleMouseMove}>
                {/*
              使用 `render`prop 动态决定要渲染的内容,
              而不是给出一个 <Mouse> 渲染结果的静态表示
            */}
                {this.props.render(this.state)}
              </div>
            );
          }
        }
    
        class MouseTracker extends React.Component {
          render() {
            return (
              <div>
                <h1>移动鼠标!</h1>
                <Mouse render={mouse => <Cat mouse={mouse} />} />
              </div>
            );
          }
        }
    
        // 示例3:
        // 如果你出于某种原因真的想要 HOC,那么你可以轻松实现
        // 使用具有 render prop 的普通组件创建一个!
        function withMouse(Component) {
          return class extends React.Component {
            render() {
              return (
                <Mouse
                  render={mouse => <Component {...this.props} mouse={mouse} />}
                />
              );
            }
          };
        }
    

    7. react-redux

    • 定义: 状态管理框架

    • 流程图: react浅析

    • 基本概念:

      • store: react-redux 总的状态容器, 是一个对象
      • action: 一个对象, 表明事件, 需要有 type 字段
      • reducer: 一个函数, 根据不同的 action 返回不同的数据 根据上面流程图, view 层可以通过两种方式来更新
        • view 发出 action => dispatcher 之后到达 reducer => reducer 处理后返回新的数据更新 View
        • 其他层发出 action 后以同样的方式更新 view
    • 总结: 发出 action => reducer 根据 action 返回不同数据 => store 被更新 => view 更新

    组件分类: react-redux 将所有组件分为 UI 组件 和 容器组件

    • UI 组件:

      • 只负责 UI 的展示
      • 没有状态(state)
      • 所有数据由 props 提供
      • 不使用 redux 的所有 API
    • 容器组件

      • 负责管理数据和所有的交互逻辑
      • 带有内部状态
      • 可以使用 redux 的 API
    • 计数器示例:

        import { connect } from "react-redux";
        import Count from "./Count";
        function mapStateToProps(state) {
          return {
            count: state.count
          };
        }
        function mapDispatchToProps(dispatch) {
          return {
            add: () => dispatch({ type: "ADD_COUNT" })
          };
        }
    
        const newComponent = connect(mapStateToProps, mapDispatchToProps)(Count);
    

    mapStateToProps

    接收 state 参数, 返回 props 对象

    mapDispatchToProps

    接收 dispatch 参数, 定义一系列发送事件的方法(发送一个 action), 返回 props

    Reducer

    刚才我们发送了 action, 但是并未对事件进行处理, reducer 实际就是来处理 action 的 示例如下:

        // counter-reducer
        export default function reducer(state = { count: 0 }, action) {
          switch (action.type) {
            case "ADD-COUNT":
              return {
                count: state.count + 1
              };
            default:
              return state;
          }
        }
    

    store

       // store示例
        import { createStore, Provider } from "react-redux";
        import React from "react";
        import reducer from "./counter-reducer";
        import Counter from "./components/Counter";
    
        const store = createStore(reducer); // 创建store
        ReactDOM.render(
          // store注册到顶层, 所有组件可以共享
          <Provider store={store}>
            <Counter />
          </Provider>,
          document.getElementById("root") // 挂载到根节点
        );
    
    • redux 总结:
      • dispatch(action) => reducer => new state => new props => update components
      • 分为容器组件和 UI 组件, 传统组件需要使用 connect 处理
      • reducer 处理 action 返回新的 state, 需要考虑 action 不匹配的情况(default)
      • 使用 creatStore 函数创建 store,reducer 作为参数
      • 使用 provider 作为顶层组件将全局 sotre 引入

    8. react fiber

    react 在进行组件渲染时, 从 setState 到渲染完成整个过程是同步的, 如果需要渲染的组件比价庞大, js 运行占用的主线程时间会比较长, 导致页面响应变差, 使得 react 在动画, 手势等应用中效果变差; 为了解决整个问题, react 团队经过两年时间, 重写了 react 的核心算法-reconciliation, 命名为 fiber

    本文持续更新中~~~


    起源地下载网 » react浅析

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元