React在构建高性能前端应用时有哪些最佳实践?

2026-04-27 19:391阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计893个文字,预计阅读时间需要4分钟。

React在构建高性能前端应用时有哪些最佳实践?

目录 + React + Hook 父组件获取子组件数据/函数 + 子组件 MyWorldMap + 父组件 MyTrip + React Hook 父组件传递子组件 form + 父组件 + 子组件 + React Hook 父组件获取子组件数据/函数 + 我们知道在 React 中,常用 props 实现子组件数据传递。

目录
  • React Hook父组件获取子组件数据/函数
    • 子组件MyWorldMap
    • 父组件MyTrip
  • React Hook父组件提交子组件form
    • 父组件
    • 子组件

React Hook父组件获取子组件数据/函数

我们知道在react中,常用props实现子组件数据到父组件的传递,但是父组件调用子组件的功能却不常用。

文档上说ref其实不是最佳的选择,但是想着偷懒不学redux,在网上找了很多教程,要不就是hook的讲的太少,要不就是父子组件傻傻分不清,于是只好再啃了一下文档,就学了一下其它hook的api。

在这里我们需要用到useImperativeHandle这个api,其函数形式为

useImperativeHandle(ref, createHandle, [deps])

其实这个api也是ref的一种形式,但是相当于做了一定的优化,可以选择让子组件只暴露一定的api给父组件,根据在文档和其他博客上给出的方法

React在构建高性能前端应用时有哪些最佳实践?

一共有两大步骤:

  • 1.将ref传递到子组件中
  • 2.需要使用forwardRef对子组件进行包装

子组件MyWorldMap

 const mapRef = useRef(null);     useImperativeHandle(ref, () => {           return {             //clickSwitch是子组件暴露的函数             clickSwitch() {                               if(type == 1){                     initChinaMap();                     setType(2);                 }else{                     initWordMap();                     setType(1);                 }                            }         }     })   //你的return内容,注意ref       return(         <React.Fragment>               <div id={"myWorldMap"} style={{ width: "800px", height: "400px" }}  ref={mapRef}></div>           </React.Fragment>         ) }     //最后要配合forwardRef MyWorldMap = forwardRef(MyWorldMap); export default MyWorldMap;

注:ref是子组件声明的时候传进来的,也就是

function MyWorldMap (props,ref){ //..你的代码 }   //export...

其实官方文档给出来的例子是:

function FancyInput(props, ref) {   const inputRef = useRef();   useImperativeHandle(ref, () => ({     focus: () => {       inputRef.current.focus();     }   }));   return <input ref={inputRef} ... />; } FancyInput = forwardRef(FancyInput);

两种方法都是可以的

父组件MyTrip

const myWordMapRef = useRef();   return(   //省略一些代码,注意ref  <MyWorldMap proData = { myMapData} handleMapClick = {handleMapClick.bind(this)} ref={myWordMapRef}>    </MyWorldMap> <div className={styles["mapButton-wrap"]}>        <ButtonGroup>                <Button onClick={() => myWordMapRef.current.clickSwitch()}>Switch</Button>                <Button onClick={()=>clickAll() }>All</Button>         </ButtonGroup>  </div> )

现在你就可以在父组件里面通过myWordMapRef.current.clickSwitch()调用函数了

React Hook父组件提交子组件form

父组件

import React, { useState, useEffect, useRef }  from 'react'; import { Button } from 'antd'; import EditClassA from './EditClassA'; export default (): React.ReactNode => {     const [isEdit,setIsEdit] = useState<boolean>(false);     const editClassARef = useRef();     const handleSave = () => {         // 调用子组件的方法         editClassARef.current.changeVal();     }     return (         <div>             {!isEdit?(                 <Button style={{marginRight:20}} onClick={()=>setIsEdit(!isEdit)}>编辑</Button>             ):(                 <Button style={{marginRight:20}} onClick={handleSave}>保存</Button>             )}         </div>         <EditClassA isEdit={isEdit} setIsEdit={setIsEdit} ref={editClassARef}/>     ) }

子组件

import React, { useImperativeHandle, forwardRef }  from 'react'; import { Form , Input } from 'antd'; import style from '@/pages/BackEnd/style.less'; const EditClassA = forwardRef((props, ref) => {     // props 里面有父组件的值和方法     const [form] = Form.useForm();     useImperativeHandle(ref, () => ({         changeVal: () => {             form             .validateFields()             .then( values => {                 // 调用父组件方法,设置父组件的值                 props.setIsEdit(!props.isEdit)             })             .catch(errorInfo => {                 return false             })         }     }));     return (     <Form form={form} name="basic" colon={false} >         <Form.Item             label="总部名称"             name="name"             initialValue="总部"             rules={[{required: true,message: '请输入总部名称',}]}>             <Input className={props.isEdit?'':style.disabledInput} placeholder="请输入" disabled={!props.isEdit}/>         </Form.Item>     </Form>     ); }) export default EditClassA

.disabledInput[disabled]{   color: rgba(0, 0, 0, 0.85);   background-color: transparent;   cursor: default;   border: unset;   border-bottom: 1px solid #333; }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

本文共计893个文字,预计阅读时间需要4分钟。

React在构建高性能前端应用时有哪些最佳实践?

目录 + React + Hook 父组件获取子组件数据/函数 + 子组件 MyWorldMap + 父组件 MyTrip + React Hook 父组件传递子组件 form + 父组件 + 子组件 + React Hook 父组件获取子组件数据/函数 + 我们知道在 React 中,常用 props 实现子组件数据传递。

目录
  • React Hook父组件获取子组件数据/函数
    • 子组件MyWorldMap
    • 父组件MyTrip
  • React Hook父组件提交子组件form
    • 父组件
    • 子组件

React Hook父组件获取子组件数据/函数

我们知道在react中,常用props实现子组件数据到父组件的传递,但是父组件调用子组件的功能却不常用。

文档上说ref其实不是最佳的选择,但是想着偷懒不学redux,在网上找了很多教程,要不就是hook的讲的太少,要不就是父子组件傻傻分不清,于是只好再啃了一下文档,就学了一下其它hook的api。

在这里我们需要用到useImperativeHandle这个api,其函数形式为

useImperativeHandle(ref, createHandle, [deps])

其实这个api也是ref的一种形式,但是相当于做了一定的优化,可以选择让子组件只暴露一定的api给父组件,根据在文档和其他博客上给出的方法

React在构建高性能前端应用时有哪些最佳实践?

一共有两大步骤:

  • 1.将ref传递到子组件中
  • 2.需要使用forwardRef对子组件进行包装

子组件MyWorldMap

 const mapRef = useRef(null);     useImperativeHandle(ref, () => {           return {             //clickSwitch是子组件暴露的函数             clickSwitch() {                               if(type == 1){                     initChinaMap();                     setType(2);                 }else{                     initWordMap();                     setType(1);                 }                            }         }     })   //你的return内容,注意ref       return(         <React.Fragment>               <div id={"myWorldMap"} style={{ width: "800px", height: "400px" }}  ref={mapRef}></div>           </React.Fragment>         ) }     //最后要配合forwardRef MyWorldMap = forwardRef(MyWorldMap); export default MyWorldMap;

注:ref是子组件声明的时候传进来的,也就是

function MyWorldMap (props,ref){ //..你的代码 }   //export...

其实官方文档给出来的例子是:

function FancyInput(props, ref) {   const inputRef = useRef();   useImperativeHandle(ref, () => ({     focus: () => {       inputRef.current.focus();     }   }));   return <input ref={inputRef} ... />; } FancyInput = forwardRef(FancyInput);

两种方法都是可以的

父组件MyTrip

const myWordMapRef = useRef();   return(   //省略一些代码,注意ref  <MyWorldMap proData = { myMapData} handleMapClick = {handleMapClick.bind(this)} ref={myWordMapRef}>    </MyWorldMap> <div className={styles["mapButton-wrap"]}>        <ButtonGroup>                <Button onClick={() => myWordMapRef.current.clickSwitch()}>Switch</Button>                <Button onClick={()=>clickAll() }>All</Button>         </ButtonGroup>  </div> )

现在你就可以在父组件里面通过myWordMapRef.current.clickSwitch()调用函数了

React Hook父组件提交子组件form

父组件

import React, { useState, useEffect, useRef }  from 'react'; import { Button } from 'antd'; import EditClassA from './EditClassA'; export default (): React.ReactNode => {     const [isEdit,setIsEdit] = useState<boolean>(false);     const editClassARef = useRef();     const handleSave = () => {         // 调用子组件的方法         editClassARef.current.changeVal();     }     return (         <div>             {!isEdit?(                 <Button style={{marginRight:20}} onClick={()=>setIsEdit(!isEdit)}>编辑</Button>             ):(                 <Button style={{marginRight:20}} onClick={handleSave}>保存</Button>             )}         </div>         <EditClassA isEdit={isEdit} setIsEdit={setIsEdit} ref={editClassARef}/>     ) }

子组件

import React, { useImperativeHandle, forwardRef }  from 'react'; import { Form , Input } from 'antd'; import style from '@/pages/BackEnd/style.less'; const EditClassA = forwardRef((props, ref) => {     // props 里面有父组件的值和方法     const [form] = Form.useForm();     useImperativeHandle(ref, () => ({         changeVal: () => {             form             .validateFields()             .then( values => {                 // 调用父组件方法,设置父组件的值                 props.setIsEdit(!props.isEdit)             })             .catch(errorInfo => {                 return false             })         }     }));     return (     <Form form={form} name="basic" colon={false} >         <Form.Item             label="总部名称"             name="name"             initialValue="总部"             rules={[{required: true,message: '请输入总部名称',}]}>             <Input className={props.isEdit?'':style.disabledInput} placeholder="请输入" disabled={!props.isEdit}/>         </Form.Item>     </Form>     ); }) export default EditClassA

.disabledInput[disabled]{   color: rgba(0, 0, 0, 0.85);   background-color: transparent;   cursor: default;   border: unset;   border-bottom: 1px solid #333; }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。