React学习记录(持续更新)

以前做项目主要用的是Vue,现在5月份加入React项目,记录平时项目中的踩坑点和接触到的注意事项。

 

1.遍历数组渲染dom需要设置key值,习惯使用数组索引做key,这样很容易出现bug。

key值应该使用唯一值,比如id等。

react监测差异时会根据key值来判断是否需要进行更新,当数组前几项被删除,后几项就会占用原来前几项的key值,key值没有发生改变,react不会对对应相同key值的dom做更新渲染。所以也不应该使用index做dom的key值。

 

2.state数据更新时如果依赖前一次的state,依照代码习惯有时候会使用如下代码

this.setState({
  counter: this.state.counter + this.props.increment,
});

但是这样设置新的state,可能会出现数据不同步或者无法更新的情况。

应该使用setState() 接收一个函数而不是一个对象。

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

 

3.React 会将小写开头的标签名认为是 HTML 原生标签,所以组件命名必须以大写开头。

 

4.函数作为子代,props.children接受传参,可参考之后灵活使用props.chidren

function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i++) {
    items.push(props.children(i));
  }
  return <div>{items}</div>;
}

function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>This is item {index} in the list</div>}
    </Repeat>
  );
}

 

5.props.chidren设置多个入口

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

 

6.如果你想让类似 falsetruenull 或 undefined 出现在输出中,你必须先把它转换成字符串 :

<div>
  My JavaScript variable is {String(myVariable)}.
</div>

 

7.react项目打包构建后页面空白。

如果是路径找不到的问题,需要在package.json中增加配置homepage:'.'

如果修改上述配置后,页面仍然是空白,请检查你是否使用的是BrowserRouter而不是HashRouter(BrowserRouter需要后端配置支持)

 

8.(疑问)为什么react只有数组才需要key值,其他的元素不需要?答案:React 有能力辨别出,更新前后元素的对应关系

// Babel转换JSX前
const element = (
  <div>
    <h3>example</h3>
    {[<p key={1}>hello</p>, <p key={2}>world</p>]}
  </div>
);

// Babel转换后
"use strict";

var element = React.createElement(
  "div",
  null,
  React.createElement("h3",null,"example"),
  [
    React.createElement("p",{ key: 1 },"hello"), 
    React.createElement("p",{ key: 2 },"world")
  ]
);

不管 props 如何变化,数组外的每个元素始终出现在 React.createElement() 参数列表中的固定位置,这个位置就是天然的 key

初学 React 时还容易产生另一个困惑,那就是为什么 JSX 不支持 if 表达式来有选择地输出(不能这样:{if(yes){ <div {...props}/> }}),而必须采用三元运算符来完成这项工作(必须这样:{yes ? <div {...props}/>} : null)。那是因为,React 需要一个 null 去占住那个元素本来的位置

*该知识点的发现,可以利用key值触发react组件的销毁和重建

比如用户相关组件,可以绑定key值为用户id代替react天然的key值,用户切换时key属性变化,组件相应也会销毁重建,这样可以避免在组件componentWillReceiveProps等生命周期中去做其他的一些代码逻辑来同步用户的切换

 

9.react性能优化----不要在 render 中重新定义函数

很多人喜欢在 render 函数中子组件通过构造一个箭头函数来传递给子组件,但是这样有一个问题就是,每次都会声明一个新的箭头函数,因而每次声明的函数都肯定是不同的,这样就无法阻止re-render

 

10.react的组件更新渲染

 

所以,合理拆分数据和组件,让未被修改地组件对改变无感知很重要。

 

11.在React中通过反模式获取props中函数的更新 

// 1. App 会传递一个 prop 给 From 表单
// 2. Form 将向下传递一个函数给 button
//    这个函数与它从 App 得到的 prop 相接近
// 3. App 会在 mounting 之后 setState,并传递
//    一个**新**的 prop 给 Form
// 4. Form 传递一个新的函数给 Button,这个函数与
//    新的 prop 相接近
// 5. Button 会忽略新的函数, 并无法
//    更新点击处理程序,从而提交陈旧的数据

class App extends React.Component {
  state = { val: "one" }

  componentDidMount() {
    this.setState({ val: "two" })
  }

  render() {
    return <Form value={this.state.val} />
  }
}

const Form = props => (
  <Button
    onClick={() => {
      submit(props.value)
    }}
  />
)

class Button extends React.Component {
  shouldComponentUpdate() {
    // 让我们假装比较了除函数以外的一切东西
    return false
  }

  handleClick = () => this.props.onClick()

  render() {
    return (
      <div>
        <button onClick={this.props.onClick}>这个的数据是旧的</button>
        <button onClick={() => this.props.onClick()}>这个工作正常</button>
        <button onClick={this.handleClick}>这个也工作正常</button>
      </div>
    )
  }
}

结果输出: 第一个‘one’,第二个第三个'two

第二次相比第一次,区别就是不是直接去执行 props.onClick,而是每次都包一个新的箭头函数,在每一次执行的时候都会去获取一个新的 this.props.onClick,这就是一切的关键,虽然 shouldComponentUpdate 为 false,但是新的 props 还是已经来了,可以通过 this.props 引用

启发:主动拉取更新的子组件来进行性能优化:像上例中的第二种和第三种方法,将子组件的 shouldComponentUpdate 返回 false,然后在传入的 props 的 handler 外面包一层匿名函数,这样每次调用 handler 都会去访问最新的 this.props.handler 等“非计划更新的 props”(函数的 props),这些函数的 props 可以返回父组件的一些内部状态传递给子组件。如此一来,子组件就从单向状态流变成了子组件向父组件主动拉取。但这与 React 的单向数据理念相左,是属奇技淫巧

 

12.React高阶组件

13.React.Children

借鉴:https://github.com/ybning/blog/issues/19

包含方法:

    map,
    forEach,
    count,
    toArray,
    only,

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值