React函数式组件 -函数式组件传值、常用hook的使用(useState、seEffect、useRef)

函数式组件

顾明思义,函数就是组件,组件就是一个函数。
函数式组件长啥呢?没错,就是如下面这样的

function App(){
   return (
       <div>hello,nice to meet you</div>
   );
}

1、看看函数式组件有哪些特点?

  • 组件的第一个参数是props,它是不可改变的,函数不能更改输入参数(接收父级传来的信息)
  • 组件中return必须写(定义该组件要渲染的内容)
  • 生命周期,无this,无state
  • 单向数据流(数据必须从较高的组件流向较低的组件)
    补充:React 16.7(beta)之前,函数组件一直被当做纯渲染组件来使用

2、组件如何传递数据的?
子级组件函数中默认有一个props参数,子级通过 props.自定义属性 获取父级传来的值

  • 父级
 function 父级组件(){
    return(
       <子级组件 自定义属性="自定义属性的值"/>
    )
  • 子级
function 子级组件(props){
   return(
      {props.自定义的属性}
   );
}

具体示例如下:

export default function App() {//父级
    return (
        <div>
            <Child info="父级传给子级的信息">
                {/* 不能这样写,无法使父级直接传给孙子级信息 */}
                {/*  */}
            </Child>
        </div>
    );
}
function Child(props) {//子级
console.log(props);//{info: "父级传给子级的信息"}
    return (
        <div>
            1-{props.info}
            {/*  */}
            {/* 下面这种方式实现了父级传给孙子级信息的目的 */}
            <Grandson info2={props.info}></Grandson>
        </div>
    );
}
function Grandson(props) {//孙子级
    console.log(props);//{info2: "父级的子级传给子级的信息"}
    return (
        <div>
            2-{props.info2}
        </div>
    );
}

3、React hooks
React hooks是React 16.8中的新增功能。它们使您无需编写类即可使用状态和其他React功能
3-1、 hook的优点:

  • 简化组件逻辑
  • 复用状态逻辑
  • 无需使用类组件编写

3-2、常用的hook:

  • useState
    添加组件的状态
    let [state, setState] = useState(initialState);
import React,{useState} from 'react';
import Child from './Child';
export default function App() { //父级
   //字符串state
   // let [name,setName] = useState("小度");
   //对象state
   let [data,setData] = useState({
      name:"小度",
      type:"智能机器人"
   });
   return (
      <div>
         {/* 父级传给子级的数据 */}
         {/*  */}
         <Child data={data}/>
         <button onClick={
            ()=>{
               // 修改字符串(修改name值)
               // setName("度小糊")
               
               // 修改对象
               setData({
                  name:"度小糊",
                  type:data.type
               })
            }}>
            点击更换
         </button>
      </div>
   );
}
import React, { useState } from 'react';
export default function Child(props) { //子级
console.log(props);
return (
    <div>
        {/* 子组件通过props接收父组件传过来的数据 */}
        {/* {props.info} */}
        <h2>name:{props.data.name}</h2>
        <h2>type:{props.data.type}</h2>
    </div>
);
}
  • useEffect
    通过使用这个 Hook,通知 React 组件需要在渲染后执行什么操作。
    React 将记住传递的 function(把这个 function 成为 “effect”),
    并在执行 DOM 更新后调用这个 function。
    可以让你能够在 function 组件中执行副作用
    可以把它看做是三个生命周期的组合体 componentDidMount、componentDidUpdate 和 componentWillUnmount

父级

 import React,{useEffect} from 'react';
 let [自定义子组件属性, 自定义函数] = useState({
      // 属性可以是任何类型,如下:属性1是string类型,属性2是number类型
      属性1: "属性值1",
      属性2: 属性值2
 })

子级

// 调用useEffect函数,两个参数,第一个参数是回调函数,第二个参数是需要检测的数据
useEffect(() => { 
   return () => {
      console.log("挂载了")
   }
}, [自定义子组件属性.属性2]); // 这里是获取从父级传来的一个属性

具体示例如下:

import React,{useState} from 'react';
export default function App() { //父级
   let [data, setData] = useState({
      name: "金毛",
      age: 3
   })
   let [show, setShow] = useState(true);
   return (
      <div>
         {show?<Child data={data} />:""}
         <button onClick={() => {
            setData({
               // 修改name值,age不变
               name: "泰迪",
               age: data.age
            })
         }}>
            点击切换
         </button>
         <button onClick={()=>{
            setShow({show:false})
         }}>
            卸载
         </button>
      </div>
   );
}
export default function Child(props) { //子级
    let {data} = props;
    let [age, setAge] = useState(8);

    useEffect(()=>{
        console.log("组件更新或挂载");
        return ()=>{
            console.log("卸载了");
        }
    // },[data.name]); //name是检测的数据
    // },[data.age]);  //age未检测
    },[age]); //数组为空也会渲染页面 

    useEffect(() => {
        return () => {
            console.log("挂载了")
        }
    }, []);

    useEffect(() => {
        return () => {
            console.log("卸载了")
        }
    }, []);

    useEffect(() => {
        return () => {
            console.log("更新了")
        }
    }, [age]);

    return (
        <div>
            {/* 接收父级传过来的数据 */}
            <h2>name:{data.name}</h2>
            {/* 

age:{data.age}

*/
} {/* 子级自身的state */} <h2>age:{age}</h2> <button onClick={() => { //每点击按钮一次就长一岁 setAge(++age); }}> 长一岁 </button> </div> ); }
  • useRef
    给dom添加唯一标识

ref创建

 import React,{useRef} from 'react';
 let 变量名 = useRef(); 

ref获取

 return( 
   <h2 ref={变量名}>{状态}</h2>
 )

具体示例如下:

// 父级代码同上例
import React,{useRef} from 'react';
export default function Child(props) {// 子级
    let {data} = props;
    let [age, setAge] = useState(8);
    let ageMark = useRef();// 创建useRef
    let [txt,setTxt] = useState("前端");
    
    useEffect(() => {
        return () => {
            console.log(ageMark.current);//标识ref的标签
        }
    });

    return (
        <div>
            <h2>name:{data.name}</h2>
            <h2 ref={ageMark}>age:{age}</h2>
            <button onClick={() => {
                setAge(++age);
            }}>
                长一岁
            </button>

            <p>{txt}</p>
            <input type="text" 
            value={txt} 
            onChange={({target})=>{
                setTxt(target.value)}
            }/>
        </div>
    );
}

注意:

  • 只在最顶层使用 Hook
  • 只在 React 函数中调用 Hook
  • 自定义 hook 时,可以调用别的hook
  • 在组件内使用 useEffect 是的可以直接从副作用中访问自身state或者任何的 props
  • 所有的 hook 必须 以 use
  • 在第一次 render 之后和每次 update 之后都会运行useEffect

你可能感兴趣的:(React,react,Rreact,hook,函数式组件)