react框架学习总结(纯干货)

Kiran ·
更新时间:2024-09-21
· 628 次阅读

首先,我先给出我学习react框架的参考教程,以下内容都是我依据此教程的个人总结。react教程

React与JSX:

function Square(props) { return ( ); }

React是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。JSX是JavaScript 的语法扩展,所以其也具有JavaScript 的全部功能,并且建议在React框架中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。
上述给出的一个奇怪的函数代码就是一个函数组件,它就是采用React框架的JSX语法,其主要体现在两点表现:一个是代码里直接嵌入HTML标签,另一个是{}里面可以嵌入表达式。这两点语法都是原生JavaScript语法所不具备的特性。
注意:jsx语法既可以写在jsx文件里也可以直接写在js文件下
其实简单看来,React框架主要功能体现在前端UI页面的渲染,包括性能优化以及操作简化等等方面。站在mvc框架的角度来看,React操作view层的功能实现。

搭建React环境:
方式一:在网站中添加React
添加一个 DOM 容器到 HTML并添加 相应的Script 标签:

react-dom

创建一个 React 组件:

'use strict'; const e = React.createElement; class LikeButton extends React.Component { constructor(props) { super(props); this.state = { liked: false }; } render() { if (this.state.liked) { return 'You liked this.'; } return e( 'button', { onClick: () => this.setState({ liked: true }) }, 'Like' ); } } const domContainer = document.querySelector('#like_button_container'); ReactDOM.render(e(LikeButton), domContainer);

直接运行打开html页面即可运行。
方式二:Create React App
此方式是通过IDE命令行的方式创建一个本地的React应用项目,也是最佳的创建方式,所以首先得在本地安装node(Node >= 8.10 和 npm >= 5.6)。
一切准备就绪后,只需一行代码即可搭建本地React框架:

npx create-react-app my-app

搭建ts版本的react框架(tsx):

npx create-react-app my-app --template typescript

这是搭建好的目录结构
jsx:
); } render() { return (

{this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)}
{this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)}
{this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)}
); } }

由上面的代码对比不难发现,函数组件适用于较为简单的功能组件,而类组件就适用于较为复杂的功能组件,类组件将在下一部分state和生命周期中具体讲解。
注意:为了更有效的区分普通函数与函数组件,所有的组件名称必须以大写字母开头。
Props:这是由React内部包装设置的一个用于传递数据的参数,Props最大的特点就是read only,即Props只能被读取使用但是不能被修改

State和(类组件)生命周期:
什么是State:Props只能读取不能修改,显然肯定满足不了用户的需求。为了满足React 组件随用户操作、网络响应或者其他变化而动态更改输出内容的功能,State出现了,它可以用户自定义。State可以被修改,但是不能直接修改,只能通过setState()函数来修改State里面的值,这也是State和Props最大的区别。
组件的生命周期:由于函数组件过于简单而这里的生命周期是指一些声明周期方法,所以这里的生命周期对于类组件而言。
组件的生命周期分为三个周期:挂载,更新和卸载。
这里的生命周期方法我不做具体讲解,大家可以参看详细的官方教程。
挂载,当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

constructor() static getDerivedStateFromProps() render() componentDidMount()

注意:render()方法是类组件中唯一必须实现的方法。因为最简单的函数组件里面的业务逻辑也包含reader()方法的业务逻辑。如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
更新,当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

static getDerivedStateFromProps() shouldComponentUpdate() render() getSnapshotBeforeUpdate() componentDidUpdate()

注意:此处说的props改变与上述说的props不可修改并不矛盾,上述说的props不可修改是指props在当前组件中不能被修改,而此处说的props改变是指在父组件因为传递参数的内容改变而导致子组件props改变。
卸载,当组件从 DOM 中移除时会调用如下方法:

componentWillUnmount()

事件处理:
React元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:

React 事件的命名采用小驼峰式(camelCase),而不是纯小写。 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

React元素的事件处理中this绑定的三种方式:
es5中的bind方法:

class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(state => ({ isToggleOn: !state.isToggleOn })); } render() { return ( ); } }

public class fields 语法:

class LoggingButton extends React.Component { // 此语法确保 `handleClick` 内的 `this` 已被绑定。 handleClick = () => { console.log('this is:', this); } render() { return ( ); } }

箭头函数:

class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // 此语法确保 `handleClick` 内的 `this` 已被绑定。 return ( ); } }

一些其它的核心概念:
元素渲染: ReactDOM.render()是最顶层的渲染方法,而组件里面的render方法可以看成它的子成员,ReactDOM.render是唯一一个直接与DOM交互的方法,而其字render方法只改变ReactDOM元素,最终都是由ReactDOM.render来更替UI的DOM元素,所以此方法建议只调用一次。
条件渲染:React 中的条件渲染和 JavaScript 中的一样,使用 JavaScript 运算符 if 或者条件运算符(包括三目运算符)去创建元素来表现当前的状态,然后让 React 根据它们来更新 UI。

render() { const isLoggedIn = this.state.isLoggedIn; let button; // 运算符 if if (isLoggedIn) { button = ; } else { button = ; } return (
{button}
); } function Mailbox(props) { const unreadMessages = props.unreadMessages; return (

Hello!

// 条件运算符 {unreadMessages.length > 0 &&

You have {unreadMessages.length} unread messages.

}
); } render() { const isLoggedIn = this.state.isLoggedIn; return (
// 三目运算符 {isLoggedIn ? : }
); }

状态提升:多个组件需要反映相同的变化数据,这时我们将共享状态提升到最近的共同父组件中去。状态提升体现的是种代码设计思想,此思想既能降低代码的耦合性还能提高代码的扩展性。
React有十分强大的组合模式。我们推荐使用组合而非继承来实现组件间的代码重用。

一个完整的较为全面覆盖的simple:
这是官网教程给出的一个井字棋游戏simple,几乎涵盖了我上面列出的所有知识点,甚至还有没提到的细节知识点。比较React是个很大的框架,我所列出的这些才只是冰山一角。
这个是游戏实现了四大功能:

tic-tac-toe(三连棋)游戏的所有功能 能够判定玩家何时获胜 能够记录游戏进程 允许玩家查看游戏的历史记录,也可以查看任意一个历史版本的游戏棋盘状态

css代码:

body { font: 14px "Century Gothic", Futura, sans-serif; margin: 20px; } ol, ul { padding-left: 30px; } .board-row:after { clear: both; content: ""; display: table; } .status { margin-bottom: 10px; } .square { background: #fff; border: 1px solid #999; float: left; font-size: 24px; font-weight: bold; line-height: 34px; height: 34px; margin-right: -1px; margin-top: -1px; padding: 0; text-align: center; width: 34px; } .square:focus { outline: none; } .kbd-navigation .square:focus { background: #ddd; } .game { display: flex; flex-direction: row; } .game-info { margin-left: 20px; }

js(jsx)代码:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; function Square(props) { return ( ); } class Board extends React.Component { renderSquare(i) { return ( this.props.onClick(i)} /> ); } render() { return (
{this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)}
{this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)}
{this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)}
); } } class Game extends React.Component { constructor(props) { super(props); this.state = { history: [ { squares: Array(9).fill(null) } ], stepNumber: 0, xIsNext: true }; } handleClick(i) { const history = this.state.history.slice(0, this.state.stepNumber + 1); const current = history[history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this.state.xIsNext ? "X" : "O"; this.setState({ history: history.concat([ { squares: squares } ]), stepNumber: history.length, xIsNext: !this.state.xIsNext }); } jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) === 0 }); } render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; return (
  • ); }); let status; if (winner) { status = "Winner: " + winner; } else { status = "Next player: " + (this.state.xIsNext ? "X" : "O"); } return (
    this.handleClick(i)} />
    {status}
      {moves}
    ); } } // ======================================== ReactDOM.render(, document.getElementById("root")); function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; }

    最后,由于我也只是个React初学者,此篇博客里面含有很多我自己的理解成分,难免会有错误理解,如果有发现错误的朋友欢迎评论区指出。路漫漫其修远,此篇博客的内容才只是React框架的冰山一角,希望能对大家有所帮助。

    奇喑 原创文章 64获赞 28访问量 1万+ 关注 私信 展开阅读全文
    作者:奇喑



    纯干货 学习 React

    需要 登录 后方可回复, 如果你还没有账号请 注册新账号