react相关知识点

一、开发环境配置

  1. 首先保证安装Node >= 6 和 npm >= 5.2版本以上的node.js环境

  2. 然后执行以下的代码,创建一个基本React-App项目

npx create-react-app my-app 
cd my-app 
npm start
  1. 删除新项目 src/ 文件夹中的所有文件。这是我们接下来要写代码的区域,在接下来的教程中将会一步步补充进来。注意:不要删除整个src文件夹,只删除文件夹中原始文件。我们将在下一步中用此项目的示例替换默认源文件。
cd src
​
# 如果你使用 Mac 或者 Linux:
rm -f *
​
# 或者, 如果你使用 Windows:
del *
​
# 然后,切换回项目文件夹
cd ..
  1. 在 src/ 文件夹中添加一个名为 index.css 的文件,这个文件中包含的 CSS代码 。在 src/ 文件夹中添加一个名为 index.js 的文件,这个文件中包含的 JS代码 。然后在 src/ 文件夹 index.js 的文件中,在其顶部添加以下 3 行代码:
import React from 'react'; 
import ReactDOM from 'react-dom'; 
import './index.css';

现在,如果您在项目文件夹中运行 npm start,并在浏览器中打开 http://localhost:3000 ,你应该看到一个空的字段。

二、jsx

  1. 这就是 JSX ,他是 JavaScrip 的一种扩展语法。推荐在 React 中使用这种语法来描述 UI 信息.
const element = <h1>Hello, world!</h1>;
  1. 你可以用 花括号 把任意的 JavaScript 表达式 嵌入到 JSX 中。
const element = <h1>Hello, {name}</h1>;
  1. 可以在 if 语句或者是 for 循环中使用 JSX,用它给变量赋值,当做参数接收,或者作为函数的返回值
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}
  1. 用 JSX 指定属性值,可以使用双引号来指定字符串字面量作为属性值,您也可以用花括号嵌入一个 JavaScript 表达式作为属性值:
const element = <div tabIndex="0"></div>;
const element = <img src={user.avatarUrl}></img>;
  1. JSX 防止注入攻击,默认情况下, 在渲染之前, React DOM 会格式化(escapes) JSX中的所有值. 从而保证用户无法注入任何应用之外的代码. 在被渲染之前,所有的数据都被转义成为了字符串处理。 以避免 XSS(跨站脚本) 攻击。

  2. Babel 将JSX编译成 React.createElement() 调用。以下连个代码是完全一样的。

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

三、元素渲染

  1. 要渲染一个 React 元素到一个 root DOM 节点,把它们传递给 ReactDOM.render() 方法
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
  1. react 元素是 不可突变(immutable) 的. 一旦你创建了一个元素, 就不能再修改其子元素或任何属性。一个元素就像电影里的一帧: 它表示在某一特定时间点的 UI 。就我们所知, 更新 UI 的唯一方法是创建一个新的元素, 并将其传入 ReactDOM.render() 方法.

  2. React DOM 会将元素及其子元素与之前版本逐一对比, 并只对有必要更新的 DOM 进行更新, 以达到 DOM 所需的状态。

四、组件和属性

  1. 从定义上来说, 组件就像JavaScript的函数。组件可以接收任意输入(称为”props”), 并返回 React 元素,用以描述屏幕显示内容。

  2. 函数式组件和类组件

//函数式
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
//类组件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
  1. 元素也可以代表用户定义的组件,组件名称总是以大写字母开始。当 React 遇到一个代表用户定义组件的元素时,它将 JSX 属性以一个单独对象的形式传递给相应的组件。 我们将其称为 “props” 对象。
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
​
const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);
//我们调用了 ReactDOM.render() 方法并向其中传入了 <Welcome name="Sara" /> 元素。
//React 调用 Welcome 组件,并向其中传入了 {name: 'Sara'} 作为 props 对象。
//Welcome 组件返回 <h1>Hello, Sara</h1>。
//React DOM 迅速更新 DOM ,使其显示为 <h1>Hello, Sara</h1>
  1. 组件可以在它们的输出中引用其它组件

  2. 不要害怕把一个组件分为多个更小的组件。

  3. Props 是只读的,无论你用函数或类的方法来声明组件, 它都无法修改其自身 props

五、状态和生命周期

  1. 用类定义的组件有一些额外的特性。 这个”类专有的特性”, 指的就是局部状态。state 和 props 类似,但是它是私有的,并且由组件本身完全控制。

  2. 把函数式组件转化为类组件

//1.创建一个继承自 React.Component 类的 ES6 class 同名类。
//2.添加一个名为 render() 的空方法。
//3.把原函数中的所有内容移至 render() 中。
//4.在 render() 方法中使用 this.props 替代 props。
//5.删除保留的空函数声明。
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
  1. 生命周期方法

componentDidMount() 钩子在组件输出被渲染到 DOM 之后运行。

componentWillUnmount() 钩子在产生的 DOM 被销毁时运行

  1. 不要直接修改 state(状态),用 setState() 代替,唯一可以分配 this.state 的地方是构造函数。
//例如,这样将不会重新渲染一个组件:
this.state.comment = 'Hello';
//用 setState() 代替:
this.setState({comment: 'Hello'});
  1. state(状态) 更新可能是异步的,React 为了优化性能,有可能会将多个 setState() 调用合并为一次更新。this.props 和 this.state 可能是异步更新的,你不能依赖他们的值计算下一个state(状态)。
//以下代码可能导致 counter(计数器)更新失败:
this.setState({
  counter: this.state.counter + this.props.increment,
});
//要解决这个问题,应该使用第 2 种 setState() 的格式,它接收一个函数,而不是一个对象。该函数接收前一个状态值作为第 1 个参数, 并将更新后的值作为第 2 个参数:
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
  1. 当你调用 setState(), React 将合并你提供的对象到当前的状态中。

  2. 无论作为父组件还是子组件,它都无法获悉一个组件是否有状态,同时也不需要关心另一个组件是定义为函数组件还是类组件。这就是 state(状态) 经常被称为 本地状态 或 封装状态的原因。 它不能被拥有并设置它的组件 以外的任何组件访问。

  3. 一个组件可以选择将 state(状态) 向下传递,作为其子组件的 props(属性):

六、处理事件

  1. 通过 React 元素处理事件跟在 DOM 元素上处理事件非常相似。但是有一些语法上的区别:

    • React 事件使用驼峰命名,而不是全部小写。

    • 通过 JSX , 你传递一个函数作为事件处理程序,而不是一个字符串。

    • 在 React 中你不能通过返回 false(即 return false; 语句) 来阻止默认行为。必须明确调用 preventDefault

    • 当使用 React 时,你一般不需要调用 addEventListener 在 DOM 元素被创建后添加事件监听器。相反,只要当元素被初始渲染的时候提供一个监听器就可以了。

  2. 一般情况下,如果你引用一个后面没跟 () 的方法,例如 onClick={this.handleClick} ,那你就应该 绑定(bind) 该方法。
    如果调用 bind 令你烦恼,有两种方法可以解决这个问题。

代码块
//方法一 使用实验性的 属性初始化语法 ,那么你可以使用属性初始值设置来正确地 绑定(bind) 回调:
class LoggingButton extends React.Component {
  // 这个语法确保 `this` 绑定在 handleClick 中。
  handleClick = () => {
    console.log('this is:', this);
  }
​
  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
​
//方法二 没有使用属性初始化语法,可以在回调中使用一个 箭头函数
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }
​
  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

七、条件渲染

  1. React 中的条件渲染就和在 JavaScript 中的条件语句一样。使用 JavaScript 操作符如 if 或者条件操作符来创建渲染当前状态的元素,并且让 React 更新匹配的 UI 。

  2. 可以用变量来存储元素。这可以帮助您有条件地渲染组件的一部分,而输出的其余部分不会更改。

  3. 使用逻辑 && 操作符的内联 if 用法,可以 在JSX中嵌入任何表达式 ,方法是将其包裹在花括号中。这也包括 JavaScript 逻辑 && 运算符。因为在 JavaScript 中, true && expression 总是会评估为 expression ,而 false && expression 总是执行为 false 。

  4. 使用条件操作符的内联 If-Else,另一个用于条件渲染元素的内联方法是使用 JavaScript 的条件操作符 condition ? true : false

  5. 在极少数情况下,您可能希望组件隐藏自身,即使它是由另一个组件渲染的。为此,返回 null 而不是其渲染输出。

八、列表(Lists) 和 键(Keys)

  1. 多组件渲染,可以创建元素集合,并用一对大括号 {} 在 JSX 中直接将其引用即可。
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);
  1. 键(Keys),帮助 React 标识哪个项被修改、添加或者移除了。数组中的每一个元素都应该有一个唯一不变的键(Keys)来标识:挑选 key 最好的方式是使用一个在它的同辈元素中不重复的标识字符串。

  2. keys 只在数组的上下文中存在意义。如果你提取 一个 ListItem 组件,应该把 key 放置在数组处理的 元素中,不能放在 ListItem 组件自身中的

  3. 根元素上。
  4. 在数组中使用的 keys 必须在它们的同辈之间唯一。然而它们并不需要全局唯一。我们可以在操作两个不同数组的时候使用相同的 keys :

  5. 键是React的一个内部映射,但其不会传递给组件的内部。如果你需要在组件中使用相同的值,可以明确使用一个不同名字的 prop 传入。

//Post 组件可以读取 props.id,但是不能读取 props.key 。
const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);
  1. 在 JSX 中嵌入 map(),JSX允许在大括号中嵌入任何表达式,因此可以 内联 map()
function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />)}
    </ul>
  );
}

九、表单

  1. 在 HTML 中,表单元素如 , 和 表单元素通常保持自己的状态,并根据用户输入进行更新。而在 React 中,可变状态一般保存在组件的 state(状态) 属性中,并且只能通过 setState() 更新。通过使 React 的 state 成为 “单一数据源原则” 来结合这两个形式。然后渲染表单的 React 组件也可以控制在用户输入之后的行为。这种形式,其值由 React 控制的输入表单元素称为“受控组件”。
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>
    );
  }
}
  1. 在 React 中, 的赋值使用 value 属性替代。

  2. 注意,选项是初始化选中的,因为它的 selected 属性。React 中,并不使用这个 selected 属性,而是在根 select 标签中使用了一个 value 属性。这使得受控组件使用更方便。您可以将一个数组传递给 value 属性,允许你在 select 标签中选择多个选项。

  3. 当您需要处理多个受控的 input 元素时,您可以为每个元素添加一个 name 属性,并且让处理函数根据 event.target.name 的值来选择要做什么。

  4. 比较成熟的表单控件方法,可以在formilk学习。

十、状态提升(Lifting State Up)

  1. 通常情况下,同一个数据的变化需要几个不同的组件来反映。我们建议提升共享的状态到它们最近的祖先组件中

  2. 在 React 中,共享 state(状态) 是通过将其移动到需要它的组件的最接近的共同祖先组件来实现的。 这被称为“状态提升(Lifting State Up)”。

  3. 在一个 React 应用中,对于任何可变的数据都应该循序“单一数据源”原则。通常情况下,state 首先被添加到需要它进行渲染的组件。然后,如果其它的组件也需要它,你可以提升状态到它们最近的祖先组件。你应该依赖 从上到下的数据流向 ,而不是试图在不同的组件中同步状态

十一、组合(Composition) VS 继承(Inheritance)

  1. React 拥有一个强大的组合模型,我们建议使用组合而不是继承以实现代码的重用。

  2. 一些组件在设计前无法获知自己要使用什么子组件,尤其在 Sidebar 和 Dialog 等通用 “容器” 中比较常见。我们建议这种组件使用特别的 children prop 来直接传递 子元素到他们的输出中:

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>
  );
}
  1. 在一个组件中你可能需要多个 “占位符” 。在这种情况下,你可以使用自定义的 prop(属性),而不是使用 children :
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 />
      } />
  );
}
  1. 我们可能说一个 WelcomeDialog 是 Dialog 的一个特殊用例。在React中,也可以使用组合来实现,一个偏“特殊”的组件渲染出一个偏“通用”的组件,通过 props(属性) 配置它
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />);
}

十二、编程思想

  1. 确定 UI state(状态)
    1.是否通过 props(属性) 从父级传入? 如果是这样,它可能不是 state(状态) 。
    2.是否永远不会发生变化? 如果是这样,它可能不是 state(状态)。
    3.是否可以由组件中其他的 state(状态) 或 props(属性) 计算得出?如果是这样,则它不是 state(状态)。

  2. react生命周期

在这里插入图片描述

React生命周期主要包括三个阶段:初始化阶段、运行中阶段和销毁阶段,在React不同的生命周期里,会依次触发不同的钩子函数

详细链接见:图解ES6中的React生命周期

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值