React 详解

1、React简介

React官网 https://react.docschina.org/

本人git demo地址:https://gitee.com/lizuoqun/web-react-lzq

1.1、React的特点

  1. 声明式编码
  2. 组件化编码
  3. React Native 编写原生应用
  4. 高效(优秀的Diffing算法)

1.2、React高效的原因

  1. 使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM。
  2. DOM Diffing算法, 最小化页面重绘。

1.3、JSX

1.3.1、JSX说明

  1. 全称: JavaScript XML
  2. react定义的一种类似于XML的JS扩展语法: JS + XML本质是React.createElement(component, props, ...children)方法的语法糖
  3. 作用: 用来简化创建虚拟DOM
    • 写法:var ele = <h1>Hello JSX!</h1>
    • 注意1:它不是字符串, 也不是HTML/XML标签
    • 注意2:它最终产生的就是一个JS对象
  4. 标签名任意: HTML标签或其它标签
  5. 标签属性任意: HTML标签属性或其它
  6. 基本语法规则
    • 遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析
    • 遇到以 { 开头的代码,以JS语法解析: 标签中的js表达式必须用{ }包含

1.3.2、渲染虚拟DOM(元素)

  1. 语法: ReactDOM.render(virtualDOM, containerDOM)
  2. 作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示
  3. 参数说明
    • 参数一: 纯js或jsx创建的虚拟dom对象
    • 参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)

2、三大核心属性

2.1、state状态

  1. state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
  2. 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

使用状态数据需要注意:

  1. 组件中render方法中的this为组件实例对象
  2. 组件自定义的方法中this为undefined,如何解决?
    • 强制绑定this: 通过函数对象的bind()
    • 箭头函数
  3. 状态数据,不能直接修改或更新

案例:定义一个展示天气信息的组件:默认展示天气炎热 或 凉爽,点击文字切换天气

    <script type="text/babel">
      class Num extends React.Component {
        // 借助构造器初始化状态
        constructor(props) {
          super(props);
          this.state = { isOne: true };
          // 绑定this
          this.changeState = this.changeState.bind(this);
        }
        changeState() {
          // 这里的this对象是undefined?
          // console.log(this)
          console.log("change");
          // 状态不能直接更改
          // this.state.isOne = !this.state.isOne;
          // 通过setState方法进行修改值,并且通过这种方法进行设置值,只会覆盖原状态下的键值,其余键值不变
          this.setState({ isOne: !this.state.isOne });
          console.log(this);
        }
        render() {
          // console.log(this);
          // 读取状态进行渲染判断
          return (
            // 绑定事件、初始化渲染时不调用函数
            <h2 onClick={this.changeState}>
              this is {this.state.isOne ? "one" : "zero"}
            </h2>
          );
        }
      }
      ReactDOM.render(<Num />, document.getElementById("app1"));
    </script>

对于这样编写代码来进行实现,还可以对代码进行简化一些:

    <script type="text/babel">
      class Num extends React.Component {
        state = { isOne: true };
        // 自定义方法,指向一个箭头函数,箭头函数内部的this等价于外部第一个的this,也就等于该类的this,故可以直接通过this拿到state
        changeState = () => {
          this.setState({ isOne: !this.state.isOne });
        };
        render() {
          return (
            <h2 onClick={this.changeState}>
              this is {this.state.isOne ? "one" : "zero"}
            </h2>
          );
        }
      }
      ReactDOM.render(<Num />, document.getElementById("app1"));
    </script>

2.2、props数据

  1. 每个组件对象都会有props(properties的简写)属性
  2. 组件标签的所有属性都保存在props中

props的作用:

  1. 通过标签属性从组件外向组件内传递变化的数据
  2. 注意: 组件内部不要修改props数据

案例:自定义用来显示一个人员信息的组件

  1. 姓名必须指定,且为字符串类型;
  2. 性别为字符串类型,如果性别没有指定,默认为男
  3. 年龄为字符串类型,且为数字类型,默认值为18
    <script type="text/babel">
      class Person extends React.Component {
        render() {
          console.log(this);
          // props 不可修改
          const { name, age, sex, date } = this.props;
          return (
            <ul>
              <li>姓名:{name}</li>
              <li>年龄:{age + 1}</li>
              <li>性别:{sex}</li>
              <li>日期:{date}</li>
            </ul>
          );
        }
      }
      // 设置校验规则
      Person.propTypes = {
        name: PropTypes.string.isRequired,
        age: PropTypes.number,
        spack: PropTypes.func,
      };
      // 设置默认值
      Person.defaultProps = {
        sex: "未知",
        date: Date(),
      };
      function spack() {
        console.log("spack...");
      }
      ReactDOM.render(
        <Person name="hyy" age="18" sex="男" spack={spack} />,
        document.getElementById("app")
      );
      const p = { name: "张三", age: 18 };
      ReactDOM.render(<Person {...p} />, document.getElementById("app1"));
      ReactDOM.render(
        <Person name="18" age={18} />,
        document.getElementById("app2")
      );
    </script>

还可以通过函数来进行定义组件使用props

    <script type="text/babel">
      function Demo(props) {
        const { name, age, sex, date } = props;
        return (
          <ul>
            <li>姓名:{name}</li>
            <li>年龄:{age}</li>
            <li>性别:{sex}</li>
            <li>日期:{date}</li>
          </ul>
        );
      }
      // 设置校验规则
      Demo.propTypes = {
        name: PropTypes.string.isRequired,
        age: PropTypes.number,
        spack: PropTypes.func,
      };
      // 设置默认值
      Demo.defaultProps = {
        sex: "未知",
        date: Date(),
      };
      const p = { name: "张三", age: 18 };
      ReactDOM.render(<Demo {...p} />, document.getElementById("app1"));
    </script>

2.3、ref节点

组件内的标签可以定义ref属性来标识自己,本质上和给标签定义id是一样的。

基本使用:

    <script type="text/babel">
      class Demo extends React.Component {
        showData = () => {
          //   const leftInput = document.getElementById("input1").value;
          //   alert(leftInput);
          alert(this.refs.ref1.value);
        };
        blurData = () => {
          alert(this.refs.ref2.value);
        };
        render() {
          return (
            <div>
              <input
                ref="ref1"
                id="input1"
                type="text"
                placeholder="点击按钮提示"
              />
              <button onClick={this.showData}>提示</button>
              <input
                ref="ref2"
                onBlur={this.blurData}
                type="text"
                placeholder="失去焦点提示"
              />
            </div>
          );
        }
      }

      ReactDOM.render(<Demo />, document.getElementById("app"));
    </script>

使用回调的ref

    <script type="text/babel">
      class Demo extends React.Component {
        showData = () => {
          alert(this.input1.value);
        };
        blurData = () => {
          alert(this.input2.value);
        };
        render() {
          return (
            <div>
              <input
                ref={(currentNode) => {
                  this.input1 = currentNode;
                }}
                id="input1"
                type="text"
                placeholder="点击按钮提示"
              />
              <button onClick={this.showData}>提示</button>
              <input
                ref={(currentNode) => {
                  this.input2 = currentNode;
                }}
                onBlur={this.blurData}
                type="text"
                placeholder="失去焦点提示"
              />
            </div>
          );
        }
      }

      ReactDOM.render(<Demo />, document.getElementById("app"));
    </script>

使用createRef API创建

    <script type="text/babel">
      class Demo extends React.Component {
        myRef = React.createRef();
        showData = () => {
          console.log(this.myRef);
          alert(this.myRef.current.value)
        };

        render() {
          return (
            <div>
              <input ref={this.myRef} type="text" placeholder="点击按钮提示" />
              <button onClick={this.showData}>提示</button>
            </div>
          );
        }
      }

      ReactDOM.render(<Demo />, document.getElementById("app"));
    </script>

3、React生命周期

组件的生命周期可分成三个状态:

Mounting(挂载):已插入真实 DOM
Updating(更新):正在被重新渲染
Unmounting(卸载):已移出真实 DOM

在React16版本之前的生命周期:
在这里插入图片描述

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
    1. constructor()
    2. componentWillMount()
    3. render()
    4. componentDidMount()
  2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
    1. shouldComponentUpdate()
    2. componentWillUpdate()
    3. render()
    4. componentDidUpdate()
  3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    1. componentWillUnmount()

在React16版本之后的生命周期:
在这里插入图片描述

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
    1. constructor()
    2. getDerivedStateFromProps
    3. render()
    4. componentDidMount()
  2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
    1. getDerivedStateFromProps
    2. shouldComponentUpdate()
    3. render()
    4. getSnapshotBeforeUpdate
    5. componentDidUpdate()
  3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    1. componentWillUnmount()

4、React-Cli

安装依赖与创建项目

全局安装
npm i -g create-react-app
创建项目
create-react-app web-lzq-react
如果安装create-react-app还是无法创建项目可使用以下命令进行操作
npx create-react-app web-lzq-react
启动项目
npm start

项目文件目录说明

文件目录名说明
public静态资源文件夹
favicon.icon网站页签图标
index.html主页面
logo192.pnglogo图
logo512.pnglogo图
manifest.json应用加壳的配置文件
robots.txt爬虫协议文件
src源码文件夹
App.cssApp组件的样式
App.jsApp组件
App.test.js用于给App做测试
index.css样式
index.js入口文件
logo.svglogo图
reportWebVitals.js页面性能分析文件(需要web-vitals库的支持)
setupTests.js组件单元测试的文件(需要jest-dom库的支持)

5、React-Router5

如果你了解vue-router,那么对于react-router来说就相对来说比较容易理解,React Router 是一个用于 React 的全功能客户端和服务器端路由库,它是一个用于构建用户界面的 JavaScript 库。React Router 可以在任何 React 运行的地方运行;在 web 上,在带有 node.js 的服务器上,以及在 React Native 上。

安装react-router5

npm install react-router-dom@5

5.1、BrowserRouter

BrowserRouter是在 Web 浏览器中运行 React Router 的推荐界面。A使用干净的 URL 将当前位置存储在浏览器的地址栏中,并使用浏览器的内置历史堆栈进行导航。

ReactDOM.render(
  <BrowserRouter>
  </BrowserRouter>,
  root
);

5.2、Link

它允许用户通过单击或点击来导航到另一个页面。在react-router-dom中,Link呈现一个可访问的<a>元素,其href指向它链接到的资源。

<Link to='/home'>Home</Link>

5.3、NavLink

默认情况下,当组件处于活动状态时,active类会被添加到<NavLink>组件中。这为从 v5 升级的大多数用户提供了相同的简单样式机制。简单来说,NavLink和Link的区别就是是否可以用来控制当前选择的路由的样式

<NavLink className="list-group-item " to="/home/news">
	News
</NavLink>

5.4、Navigate

navigate顾名思义是导航的意思,当元素呈现时就会更改当前位置。

<Navigate to="/home" />

5.5、Router和Routers

这两个表达的意思就相当于一串的路由数据,当进行页面路由访问的时候还会从上至下进行逐层判断是否跳转

<Routes>
	<Route path="/lzq/about" component={About}></Route>
	<Route path="/lzq/home" component={Home}></Route>
	<Route path="/about" component={About}></Route>
</Routes>

5.6、Redirect

Redirect 重定向

<Redirect to="/null"></Redirect>
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
React Hooks 是 React 16.8 中新增的特性,它可以让你在函数组件中使用 state、生命周期钩子等 React 特性。使用 Hooks 可以让你写出更简洁、可复用且易于测试的代码。 React Hooks 提供了一系列的 Hook 函数,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useImperativeHandle、useLayoutEffect 和 useDebugValue。每个 Hook 都有特定的用途,可以帮助你处理不同的问题。 下面是 React Hooks 的一些常用 Hook 函数: 1. useState useState 是最常用的 Hook 之一,它可以让你在函数组件中使用 state。useState 接受一个初始状态值,并返回一个数组,数组的第一个值是当前 state 值,第二个值是更新 state 值的函数。 ``` const [count, setCount] = useState(0); ``` 2. useEffect useEffect 可以让你在组件渲染后执行一些副作用操作,比如订阅事件、异步请求数据等。useEffect 接受两个参数,第一个参数是一个回调函数,第二个参数是一个数组,用于控制 useEffect 的执行时机。 ``` useEffect(() => { // 这里可以执行副作用操作 }, [dependencies]); ``` 3. useContext useContext 可以让你在组件树中获取 context 的值。它接受一个 context 对象,并返回该 context 的当前值。 ``` const value = useContext(MyContext); ``` 4. useRef useRef 可以让你在组件之间共享一个可变的引用。它返回一个对象,该对象的 current 属性可以存储任何值,并在组件的生命周期中保持不变。 ``` const ref = useRef(initialValue); ref.current = value; ``` 5. useCallback useCallback 可以让你缓存一个函数,以避免在每次渲染时都创建一个新的函数实例。它接受一个回调函数和一个依赖数组,并返回一个 memoized 的回调函数。 ``` const memoizedCallback = useCallback(() => { // 这里是回调函数的逻辑 }, [dependencies]); ``` 6. useMemo useMemo 可以让你缓存一个计算结果,以避免在每次渲染时都重新计算。它接受一个计算函数和一个依赖数组,并返回一个 memoized 的计算结果。 ``` const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` 以上就是 React Hooks 的一些常用 Hook 函数,它们可以帮助你更好地处理组件状态、副作用、上下文和性能优化等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Modify_QmQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值