React 学习总结


提示:以下是本篇文章正文内容,下面案例可供参考

一、React安装

静态文件方式

你可以直接使用静态文件CDN的React CDN 库,地址如下

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

也可以使用官方提供的 CDN地址:

<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<!-- 生产环境中不建议使用 -->  
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

第一个实例:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<title>Hello React!</title>
  <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
  <div id="example"></div>
  
  <script type="text/babel">
    ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
    );
  </script>
 
</body>
</html>

npm方式安装

搭建本地环境

npx create-react-app my-app

参考链接: https://react.docschina.org/tutorial/tutorial.html#setup-option-2-local-development-environment

二、JSX

JSX 在 React 中是可选的,开发人员也经常使用这种语法

1. JSX 是什么

JSX 是一个基于 JavaScript + XML 的一个扩展语法。它可以作为值使用;但并不是字符串,也不是HTML;它可以配合JavaScript表达式一起使用

2. JSX 优点

  • JSX执行更快,因为它在编译为JavaScript代码后进行了优化
  • 它是类型安全的,在编译过程中就能发现错误
  • 使用JSX编写模块更加简单快速

3. JSX 语法

1. 如果输出多行结构,可以使用一对小括号来包含整个结构

const App = (
	<div>
  	<h1>前端学习</h1>
  </div>
)

⚠ 注意:JSX 只能有一个顶级父元素

2. 在 JSX 中可以嵌套表达式

let name = '前端';
const App = (
	<div>
  	<h1>{ name }</h1>
  </div>
)

if/for/while这些都是语句,JSX不支持语句

<h1>{ if(true) {...} }</h1>

3. JSX 中的注释

<div>
  { /* 注释 */}
</div>

4. JSX 更偏向于 JavaScript,所以对于一些特殊的属性,使用的是 JavaScript 中的属性名风格

const App = (
	<div class="box1"></div>
)const App = (
	<div className="box1"></div>
)

5. 为了更加方便的操作元素的style,针对style这个属性有特殊的处理

const App = (
	<div style={{ width:'100px' }}>
  </div>
)
// 这里的两个 '{{ }}',外部的大括号表示的是前面说的表达式语法中的大括号,
// 里面的大括号是表示对象的大括号
let skin = { width: '100px' }

6. JSX 中的表达式也可以使用在属性上,但是使用的时候需要注意;不要使用引号包含

let id = '0001';
const App = (<div id="{id}"></div>);const App = (<div id={id}></div>);

三、React创建组件的方式和区别

前提:html文件引入了react 库 或者 搭建了本地环境

1. 无状态函数式组件

function HelloComponent(props) {
  return <h1>Hello { props.name }</h1> 
  或者
  return(
  	<h1>Hello { props.name }</h1>
  )
}
ReactDOM.render(
	<HelloComponent />,
    document.getElementById('root')
)

无状态的创建形式使代码的可读性更好,并且减少了大量冗余的代码,精简只有一个render方法,大大的增强了编写一个组件的便利,除此之外无状态组件还有以下几个显著的特点:
① 组件不会被实例化,整体渲染性能得到提升
因为组件被精简成一个render方法的函数来实现的,由于是无状态组件,所以无状态组件就不会再有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。

② 组件不能访问 this对象
无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:this.refthis.state等均不能访问。若想访问就不能使用这种形式来创建组件。

③ 组件无法访问生命周期的方法
因为无状态组件是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会 实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。

④ 无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用
无状态组件被鼓励在大型项目中尽可能以简单的写法来分割原本庞大的组件,未来React也会这种面向无状态组件在譬如无意义的检查和内存分配领域进行一系列优化,所以,只要有可能,尽量使用无状态组件

2. React.createClass

这种方式已经被淘汰,所以不做过多介绍。

3. React.Component

class App extends React.Component {
		constructor(props) {
    		super(props);
      	    this.state = {
        	  value: 0
            }
    }
  	render() {
    	return(
      	  <div></div>
       )
    }
}
ReactDOM.render(
	<App />,
    document.getElementById('root')
)

补充一点

无状态组件内部其实是可以使用 ref 功能的,虽然不能通过通过 this.refs 访问到,但是可以通过将 ref 内容保存到无状态组件内部的一个本地变量中获取到

例如下面这段代码可以使用ref来获取组件挂载到dom中后所指向的dom元素

function HelloComponent(props) {
	let ref;
  return(
  	<div>
    	<div ref={ (node) => ref=node }>
      	...
      </div>
    </div>
  )
}

💤总结:

不需要使用状态 state 和 访问 this 对象的时候建议使用无状态函数式组件定义;
如果含有状态,需要访问this对象,则推荐使用 React.Component

四、组件&props

组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。

// 函数组件
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
// class 组件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

五、state&生命周期

1. state

一般使用到 state,我们应该用 class 组件

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

💤 总结

  1. 不要直接修改state,通过 this.setState 修改
  2. this.setState({}) 构造函数是唯一可以给 this.state 赋值的地方
  3. 异步时,this.setState 接收一个函数而非一个对象
  4. state 除了拥有并设置了它的组件,其它组件无法访问
  5. state 使用的情况:用户输入的搜索词、复选框是否选中的值
// 2. 异步解释
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
或者
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

2. 生命周期

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
//componentDidMount()方法会在组件已经被渲染到 DOM 中后运行
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
//componentDidMount()方法会在组件从 DOM 中移除时运行
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

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

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

六、事件处理

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

💤 总结

  • 事件属性命名使用小驼峰,JSX传入一个函数,而非字符串
  • 不能通过 false 方式阻止默认行为,可通过显式 preventDefault
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 为了在回调中使用 `this`,这个绑定是必不可少的
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

💤 总结
为了在回调中使用 this
方式① :在 constructor 中改变 this 指向

this.handleClick = this.handleClick.bind(this)

方式②:使用箭头函数

<button onClick={ () => this.handleClick }></button>

向事件处理程序传递参数

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

上述两种方式是等价的,分别通过箭头函数Function.prototype.bind 来实现。
在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。


七、条件渲染

可参考官方文档:https://react.docschina.org/docs/conditional-rendering.html

八、列表&key

可参考官方文档:https://react.docschina.org/docs/lists-and-keys.html

九、表单

1. 受控组件

在 HTML 中,表单元素(如、 和 )之类的表单元素通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 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('提交的名字: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          名字:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="提交" />
      </form>
    );
  }
}

💤 总结

  • 受控组件的事件处理函数程序接收 event 对象,可通过 event.target.value 获取受控组件的值
  • 在受控组件上指定 value 的 prop 会阻止用户更改输入。如果你指定了 value,但输入仍可编辑,则可能是你意外地将value 设置为 undefined 或 null

十、状态提升

可参考官方文档:https://react.docschina.org/docs/lifting-state-up.html

十一、组合 vs 继承

1. 组合

  • props.children
    这使得别的组件可以通过 JSX 嵌套,将任意组件作为子组件传递给它们
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>
  );
}

少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用 children,而是自行约定:将所需内容传入 props,并使用相应的 prop。

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 />
      } />
  );
}
  • 特例关系
    在 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!" />
  );
}

十二、不可变性

时间旅行,即保存历史记录
可参考官方文档:https://react.docschina.org/tutorial/tutorial.html#adding-time-travel

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 学习 React 源码是一项很有益的学习活动,可以帮助你加深对 React 的理解,并且为你提供有关如何实现组件化和声明式编程的知识。 在学习 React 源码时,我有几个建议: 1. 先从官方文档入手,了解 React 的基本概念和使用方法。这将有助于你更好地理解 React 源码。 2. 认真阅读源码注释。React 的源码非常详细,并且有很多注释,这些注释很有帮助,可以帮助你理解源码的目的和工作原理。 3. 使用调试工具,以帮助你更好地理解源码的工作流程。比如,可以使用浏览器的开发者工具调试 React 代码,或者使用断点调试。 4. 尝试实现一些自己的功能,并结合源码来调试和理解。这将有助于你更好地理解 React 的工作原理,并且能够让你在实际使用中更加熟练。 5. 可以尝试加入 React 开源社区,与其他 React 开发者交流经验,也可以参与 React 的开源项目,为 React 贡献代码。这将有助于你不断学习和提升。 ### 回答2: 学习React源码是一个非常有挑战性但也非常有价值的任务。首先,我建议你先熟悉React的基本概念和使用方法,理解React的核心思想和设计理念,然后再深入研究源码。以下是一些具体的建议: 1. 掌握JavaScript和ES6的基础知识:React源码是用JavaScript编写的,因此对于JavaScript的理解是必要的。确保你对JavaScript中ES6的新特性例如模块导入导出、箭头函数、解构赋值等有一定的了解。 2. 阅读官方文档和源码注释:React官方提供了非常详细的文档和源码注释,阅读它们可以帮助你快速了解React的内部工作原理和实现细节。 3. 从顶层开始分析:从React的顶层入手,逐步深入源码。首先阅读React的入口文件,了解React是如何初始化和渲染组件的。然后再深入了解React组件的生命周期和更新机制。 4. 使用工具进行调试:使用Chrome DevTools等工具进行调试可以帮助你更好地理解和分析React的运行时行为。通过在源码中设置断点并观察变量的值,可以深入理解React的执行流程。 5. 理解虚拟DOM和协调算法:React的核心是虚拟DOM和协调算法,学习和理解它们对于深入理解React源码非常重要。阅读相关的源码实现,将有助于你理解React如何高效地更新DOM。 6. 参考社区资源和开源项目:React有一个非常庞大的社区,许多优秀的开源项目可以帮助你更好地理解React源码。与其他人一起学习和讨论,参与到React相关的开源项目中,将加快你的学习进度。 总结起来,学习React源码需要坚实的JavaScript基础和对React的理解。通过仔细阅读官方文档、源码注释和调试工具的使用,以及参考社区资源和开源项目,你将能够逐渐深入了解React的实现细节,提高自己的技术水平。 ### 回答3: 学习React源码的过程可以相当艰巨,但也是丰富而值得的。以下是几些建议帮助你更好地学习React源码: 1. 先理解React的核心概念:在深入研究源码前,先确保你对React的基本理念和工作方式有了清晰的理解。了解虚拟DOM、组件生命周期、状态管理和数据流等核心概念将有助于更好地理解源码。 2. 创建一个简单的React应用:在学习React源码时,建议你尝试创建一个简单的React应用并深入研究它的实现细节。这样可以帮助你更好地理解React的工作原理和内部机制。 3. 阅读React官方文档和源码注释:React源码中有丰富的注释,它们会对源码的实现细节进行解释和说明。同时,React官方文档也提供了很多有价值的内容,包括API文档和设计原则。阅读这些内容能够帮助你更好地理解React的思想和设计理念。 4. 利用调试工具:学习源码的过程中,调试工具是非常有用的辅助资源。使用断点和调试器来观察源码的执行路径和状态变化,可以帮助你更好地理解代码的运行机制。 5. 参考优秀的源码解析和开源项目:很多开发者在学习React源码后,会产生一些优秀的博客文章、视频教程和开源项目,其中包含了他们对源码的解析和实践。阅读这些资源可以帮助你更好地理解React源码并从中获取灵感。 学习React源码需要耐心和持续努力,希望以上建议能够帮助你更好地进行这个过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值