乐趣区

关于前端:组长指出了我使用react常犯的错误

背景

年底了,换了项目组,新的项目组应用 react,从 vue 到 react,我只花了一天的工夫,看了官网简略的文章之后,就感觉这玩意很简略啊,比起 vue 的那么 api 来说,这基本没有学习老本好吧,十分迅速的就进入了 react 的我的项目开发,并且怏怏不乐,依据我多年的教训来看,这波必定会失去领导的赏识

很快,我就做完了我的需要,把代码提交下来,组长可能的确比拟闲,还 review 了我的代码,并且指出了一系列的问题,并通知我说学习 react 最难的局部,并不是晓得怎么应用它,而是要晓得怎么可能编写良好,洁净的 react 代码

次要给我提了六点谬误,我置信在座的各位,可能须要对号入座

在不须要应用 state 的时候应用 state

波及到我的项目中的代码逻辑,咱们将一些内容通过 demo 的模式展现进去

提交表单在很多场景下都须要用到,对于一些表单的提交,大多数人的代码的实现可能是以下形式

export default function App() {const [name, setName] = useState("");
  const submit = (e) => {e.preventDefault();
    console.log(name);
  };
  const change = (e) => {setName(e.target.value);
  };
  return (
    <div className="container">
      <form onSubmit={submit}>
        <label htmlFor="name"> 姓名: </label>
        <input value={name} onChange={change} type="text" id="name" />
      </form>
    </div>
  );
}

页面上有一个姓名输入框,通过 state 的形式将数据绑定,提交的时候从 state 上再把数据取到,这一点的确很像 vue 的双向绑定,通过 state 的形式实现了,看着外表没有问题,并且页面也出现了,submit 的数据也取到了

然而实际上,咱们并没有在别的中央应用这个 name 状态,除了在提交的时候,有人会说,value 也用到了,然而实际上你是能够不须要 value 这个字段的,只有提交的时候才会用到这个数据,所以这里齐全能够不应用 state,避免组件刷新

只须要通过 ref 改一下即可

export default function App() {const nameRef = useRef(null);
  const submit = (e) => {e.preventDefault();
    console.log(nameRef.current.value);
  };
  return (
    <div className="container">
      <form>
        <label htmlFor="name"> 姓名: </label>
        <input ref={nameRef} type="text" id="name" />
      </form>
      <button onClick={submit}> 提交 </button>
    </div>
  );
}

和之前一样,咱们点提交按钮的时候获取到了最新数据,并且页面没有屡次刷新

useState 的回调函数

那什么状况下应用 useState 呢?这种在页面上出现的内容须要应用,比方一个计数器

export default function App() {const [count, setCount] = useState(0);
  const submit = (val) => {setCount(count + val);
  };
  return (
    <div className="container">
      <button onClick={() => submit(-1)}>-1</button>
      <span>{count}</span>
      <button onClick={() => submit(1)}>+1</button>
    </div>
  );
}

外表看着没有问题,点击加减也都挺失常的,然而如果你是相熟 useState 的话,你也会给 setCount 传递一个函数的模式,这两者表现形式仿佛齐全一样,感触不到区别

const submit = (val) => {setCount((current) => current + val);
};

那具体的区别在哪呢?在不应用回调函数的时候,如果咱们间断更新状态的话,像上面这样

setCount(count + val)
setCount(count + val)

实际上页面也只会加一次,因为在这一次的更新过程中,count 的值是固定的,也就是咱们常说的 setState 是异步的起因(当你更改状态的时候,它不会立即更新,而是等到下一次 render 才会更新),并且 react 会将 state 进行批处理,然而如果是函数的模式

const submit = (val) => {setCount((current) => current + val);
  setCount((current) => current + val);
};

就可能失去想要的后果,所以如果你想应用之前的状态来进行 state 值的批改,最好应用函数模式

state 异步更新,useEffect 的应用

通过上一个 count,咱们晓得咱们立即获取 count 值的时候获取到的不是最新值

const submit = (val) => {setCount((current) => current + val);
    console.log(count);
  };

这时候有人就想到了 useEffect,如此就获取到了新的值

useEffect(() => {console.log(count)
}, [count])

而后对于这一点,很多同学就将 useEffect 当成了 vue 中的 watch,实现了上面的逻辑

export default function App() {const [user, setUser] = useState("");
  const [name, setName] = useState("");
  const [userName, setUserName] = useState("");

  useEffect(() => {setUserName(user + name);
  }, [user, name]);

  return (
    <div className="container">
      <input
        type="text"
        value={user}
        onChange={(e) => setUser(e.target.value)}
      />
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <span>{userName}</span>
    </div>
  );
}

咋一看如同没什么问题,并且实现了对应的性能,然而它不是最佳形式

理论齐全能够不必 userName 这个 state,间接在 dom 中 <span>{user + name}</span> 就能实现对应的成果

有时候很多同学也会应用 useEffect 进行上面的操作

useEffect(() => {fetch('#').then(d => setData(d))
}, [])

useEffect(() => {console.log(d)
}, [d])

那为什么你不把 console.log 的逻辑放在.then 外面呢?

常见 useEffect 谬误

const [user, setUser] = useState("");
const person = {user}
useEffect(() => {console.log(person)
}, [person])

这种状况,大多数会认为 useEffect 会在组件初始化的时候执行一次,但实际上 useEffect 中的回调会执行屡次,因为 person 是个援用类型,每次的指针地址都是变动的

这个时候你能够应用 useMemo 来解决这个问题

const person = useMemo(() => ({user}), [user])

依赖问题

因为业务很简单,所以在一直迭代的过程中,咱们的 effect 通常就会变成这种状况

useEffect(() => {......}, [person, name, age, id, status, address ....])

依赖会越来越多,略微改其中的一个点,就会执行 effect 大片的逻辑,这里最好可能拆分或者合并,确定要执行一个逻辑的,最好放在一个 state 中,比方能够将 age,name,id,等根底信息放在一个 state,而后这个 effect 依赖这一个 state 就能够了,进行 state 合并

总结

上述就是一些根底 react 使用者常呈现的一些问题,hook 的确能给咱们带来很大的便当,然而有时候从 vue 到 react,其中的一些思维还是须要做一些调整,能力更好的适应 hooks 的形式,咱们能够多看看好的一些 hooks 的封装,加深一些 hooks 的了解,也欢送大家关注公众号【FE 情报局】, 一起探讨一些技术文章

退出移动版