React官方文档学习笔记(一)

(一)JSX

JSX的表达式要放在大括号中,推荐在 JSX 代码的外面扩上一个小括号,这样可以防止分号自动插入的bug。

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);
复制代码

Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用,下面两种方法效果等同。

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
复制代码
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
复制代码

React DOM 在渲染之前默认会过滤所有传入的值。它可以确保你的应用不会被注入攻击。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(跨站脚本) 攻击。

(二)元素渲染

将React元素渲染到根DOM节点中。

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
复制代码

React元素都是不可变的。当元素被创建之后,无法改变其内容或属性,目前的方法是创建新的元素,然后将它传入ReactDOM.render()方法。(经典例子计时器:每隔一秒生成新的元素放入render渲染,不过render基本只调用一次,接下来可以用state来改变页面的数据)

React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。

(三)组件 & Props

函数定义/类定义组件
//函数定义组件
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
//类定义组件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
复制代码

(四)State & 生命周期

将函数转换为类

使用类就允许我们使用其它特性,例如局部状态、生命周期钩子

状态更新可能是异步的

this.props 和 this.state可能是异步更新的,不应该依靠它们的值来计算下一个状态。

//此代码可能无法更新计数器
this.setState({
  counter: this.state.counter + this.props.increment,
});
// 箭头函数
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));
// 常规函数
this.setState(function(prevState, props) {
  return {
    counter: prevState.counter + props.increment
  };
});
复制代码
经典时钟案例
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(() => this.tick(),1000);
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({date: new Date()});
  }

  render() {
    return (
      <div>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
复制代码

(五)事件处理

事件绑定方法
//传统的 HTML
<button onclick="activateLasers()">
  Activate Lasers
</button>

//React
<button onClick={activateLasers}>
  Activate Lasers
</button>
复制代码
向事件处理程序传递参数
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
复制代码

上述两种方式是等价的,分别通过 arrow functions 和 Function.prototype.bind 来为事件处理函数传递参数。

上面两个例子中,参数 e 作为 React 事件对象将会被作为第二个参数进行传递。通过箭头函数的方式,事件对象必须显式的进行传递,但是通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

(六)条件渲染

(七)列表 & Keys

基础列表组件

让我们来给每个列表元素分配一个 key 来解决上面的那个警告:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
        {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
复制代码
Keys

当元素没有确定的id时,你可以使用他的序列号索引index作为key。如果列表可以重新排序,我们不建议使用索引来进行排序,因为这会导致渲染变得很慢。

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);
复制代码
用keys提取组件
function ListItem(props) {
  // 对啦!这里不需要指定key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 又对啦!key应该在数组的上下文中被指定
    <ListItem key={number.toString()}
              value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
复制代码

(八)表单

受控组件
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
复制代码
多个输入的解决方法
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}
复制代码

由于 value 属性是在我们的表单元素上设置的,因此显示的值将始终为 React数据源上this.state.value 的值。由于每次按键都会触发 handleChange 来更新当前React的state,所展示的值也会随着不同用户的输入而更新。

(九)状态提升

(十)组合 vs 继承

组合
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

ReactDOM.render(
  <WelcomeDialog />,
  document.getElementById('root')
);
复制代码

JSX 标签内的任何内容都将通过 children 属性传入 FancyBorder。

思考: 顺带扩充的还可以了解:Vue双向绑定的实现原理。

额外思考:为什么React不自带双向绑定。

附加思考题:Vue和React的原理,Vue和React的相同点与不同点等等。

额外附加思考题:从template到页面显示一个dom,Vue的执行过程是怎么样的。

从render函数到显示一个dom,React的执行过程是怎么样的。

如果能把这些附加题搞明白,面试可以过我这一关了。(O(@_@)O)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值