You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classMyComponentextendsComponent{renderRow=(index)=>{// 这将无法工作,ref 将被添加到 DataTable 上,而非 MyComponent 上:return<inputref={'input-'+index}/>;// This would work though! Callback refs are awesome.return<inputref={input=>this['input-'+index]=input}/>;}render(){return<DataTabledata={this.props.data}renderRow={this.renderRow}/>}}
// BadfunctionPosts(){const[list,setList]=useState([]);useEffect(()=>{fetchPosts().then(setList);},[]);returnlist.map((post,index)=><inputkey={index}defaultValue={post.title}/>);}// GoodfunctionPosts(){const[list,setList]=useState([]);useEffect(()=>{fetchPosts().then(setList);},[]);returnlist.map(post=><inputkey={post.id}defaultValue={post.title}/>);}// Good - 如果没有 id 等唯一标识,可以由前端主动生成唯一标识functionPosts(){const[list,setList]=useState([]);useEffect(()=>{fetchPosts().then(list=>{for(constpostoflist){post.id=SomeLibrary.generateUniqueID();}setList(list);});},[]);returnlist.map(post=><inputkey={post.id}defaultValue={post.title}/>);}
[注意] 单页应用中应避免使用 location.href = 'url to jump' 进行应用内部跳转
解释:
location.href='url to jump'会导致页面刷新导致重新请求静态资源。// BadfunctionFoo(){consthandleClick=useCallback(()=>{location.href='/path/to/jump';});return<divonClick={handleClick}>点击</div>;}// GoodfunctionFoo(){consthistory=useHistory();consthandleClick=useCallback(()=>{// 在 react-router 中使用其 history 对象进行跳转history.push('/path/to/jump');});return<divonClick={handleClick}>点击</div>;}
The text was updated successfully, but these errors were encountered:
前言
规则来源于
愿望
JSX
[强制] 没有子节点的组件使用自闭合语法(react/self-closing-comp)
解释:
JSX与HTML不同,所有元素均可以自闭合。
[强制] 保持起始和结束标签在同一层缩进(react/jsx-wrap-multilines)
解释:
代码样式。
[强制] 自闭合标签的/>前添加一个空格(react/jsx-space-before-closing)
解释:
代码样式。
API
[强制] 禁止为继承自 PureComponent 的组件编写 shouldComponentUpdate 实现(react/no-redundant-should-component-update)
解释:
在 React 的实现中,PureComponent 并不直接实现 shouldComponentUpdate,而是添加一个 isReactPureComponent 的标记,由 CompositeComponent 通过识别这个标记实现相关的逻辑。因此在 PureComponent 上自定义 shouldComponentUpdate 并无法享受 super.shouldComponentUpdate 的逻辑复用,也会使得这个继承关系失去意义。
相关的 issue:facebook/react#9239
补充:
相关的 issue:facebook/react#14463
相关的代码:https://github.com/reduxjs/react-redux/blob/754c1059ded0c1ea3a9b6dc1d870e31c22d8c3b7/src/components/connectAdvanced.js#L443
[强制] 禁止使用 String 类型的 Refs(react/no-string-refs)
解释:
它已过时并可能会在 React 未来的版本被移除。
补充:
相关 issue:facebook/react#8333 (comment)
String 类型的 Refs 存在的问题:
[强制] 避免使用不安全的生命周期函数 componentWillMount、componentWillReceiveProps、componentWillUpdate(react/no-unsafe)
解释:
以上生命周期函数被 React 官方视为是不安全的,公司 react 规范中推荐使用 constructor 代替 componentWillMount,具体生命周期迁移参考『迁移过时的生命周期』。
备注:
React 官方视为以上生命周期不安全的原因是:对于 Concurrent 模式(实验性)这个未来特性,避免在 willMount / willUpdate 等生命周期挂钩中产生副作用非常重要。因为 React 当前的渲染分为 reconcile 和 commit 两个阶段,reconcile 阶段可以被高权重用户事件中端导致重复执行,由于以上生命周期函数在此阶段中被调用,导致这些生命周期函数存在被重复调用的可能。
React RFC 0006-static-lifecycle-methods:https://github.com/reactjs/rfcs/blob/master/text/0006-static-lifecycle-methods.md
React v16.9.0 更新日志:https://react.docschina.org/blog/2019/08/08/react-v16.9.0.html
迁移过时的生命周期:https://react.docschina.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles
Concurrent 模式介绍 (实验性):https://react.docschina.org/docs/concurrent-mode-intro.html
(:з[__] Dan 宝在 stackoverflow 上的回答 - 在 React 中,我应该在 componentWillMount 还是 componentDidMount 中进行初始网络请求?https://stackoverflow.com/a/41612993
[强制] 禁止使用数组索引作为 key(react/no-array-index-key)
解释:
React 使用 key 来判断哪些元素已经改变、添加或删除。
补充:
在此多说一些,我想一定有人和我之前的一样对 key 存在这样的误解,key 的目的是为了更好的性能。不,这不是事实。
key 的主要目的是作为唯一标识,在 fiber diff 阶段能够正确地判断出元素改变、添加或删除状态,尤其是对自身拥有状态的组件,这非常重要。
而在此前提下,对于属性没有变更的组件,只有实现了 shouldComponentUpdate / memo 方法,才可以避免重复渲染。
相关 issue:facebook/react#1342 (comment)
Understanding the key prop: https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js/43892905#43892905
[建议] 避免在JSX的属性值中直接使用对象和函数表达式(react/jsx-no-bind)
解释:
PureComponent 使用 shallowEqual 对 props 和 state 进行比较来决定是否需要渲染,而在 JSX 的属性值中使用对象、函数表达式会造成每一次的对象引用不同,从而 shallowEqual 会返回 false,导致不必要的渲染。
补充:
函数组件中为避免子组件刷新,可使用 useCallback 和 useMemo 等 hook 来保持函数、对象类型的属性引用不变。
[建议] 禁止在函数组件上使用 defaultProps(react/require-default-props,ignoreFunctionalComponents: true)
解释:
defaultProps 在类中非常有用,因为 props 对象被传递给许多不同的方法,如生命周期、回调等。每一个都有自己的作用域。这导致使用 JS 默认参数变得困难,因为您必须在每个函数中反复确定相同的默认值。
但是,在函数组件中,实际上不需要这种模式,因为您可以只使用 JS 默认参数,并且通常这些值的所有使用的位置都在同一作用域内。
React 团队之后的计划为,当在没有
.prototype.isReactComponent
的组件上使用defaultProps
时,createElement 将发出警告。这包括那些特殊的组件,如forwardRef
和memo
。如果 props 整体进行传递,那么升级将变得困难,不过你总是可以在需要时对它进行重构。
function Foo({foo = 1, bar = "hello"}) {
let props = {foo, bar};
//...
}
补充:
React RFC 0000-create-element-changes:http://0000-create-element-changes.md/ https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#detailed-design
[注意] 单页应用中应避免使用 location.href = 'url to jump' 进行应用内部跳转
解释:
The text was updated successfully, but these errors were encountered: