React hooks学习笔记(5)——自定义hooks

直接看demo,在components下新建HooksDemo.js:

import React from 'react';

const MOCK_DATA = [
    {
        name: "zhangsan",
        age: 18
    },
    {
        name: "lisi",
        age: 10
    }
];
export default function HooksDemo() {
    return (
        <ul>
            {MOCK_DATA.map(e => (
                <li key={e.name}>
                    {e.name}---{e.age}
                </li>
            ))}
        </ul>
    );
}

同样地在App.js中引入:

...
import HooksDemo from './components/HooksDemo';

function App() {
 ...
  return (
    <div>
         ...
       <HooksDemo />
    </div>
  );
}

在这里做的是在前台模拟一些后台数据,这里是两个用户。

实际上请求后台是有延时的,结合前面的useState,HooksDemo.js的写法会更接近于下面这种形式:

import React, { useEffect, useState } from 'react';

const MOCK_DATA = [
    {
        name: "zhangsan",
        age: 18
    },
    {
        name: "lisi",
        age: 10
    }
];
export default function HooksDemo() {
    const [users, setUsers] = useState([]);
    useEffect(() => {
        setTimeout(() => { // 模拟后台请求,实际上可能为axios或者ajax
            setUsers(MOCK_DATA);
        }, 2000);
    }, []);
    return users.length === 0? 'Loading!'
    : (
        <ul>
            {users.map(e => (
                <li key={e.name}>
                    {e.name}---{e.age}
                </li>
            ))}
        </ul>
    );
}

使用randomuser这个接口,页面会更贴近真实案例(原视频cnnodejs.org我的网络打不开):

import React, { useEffect, useState } from 'react';

export default function HooksDemo() {
    const [users, setUsers] = useState([]);
    useEffect(() => {
        fetch("https://api.randomuser.me/?nat=US&results=2") // 2 denotes that generating 2 users.
        .then(res => res.json())
        .then(json => setUsers(json.results));
    }, []);
    return users.length === 0? 'Loading!'
    : (
        <ul>
            {users.map(e => (
                <li key={e.email}>
                    {e.name.first}---{e.dob.age}
                </li>
            ))}
        </ul>
    );
}

效果图:

现在有一个需求,点击li的一个item,右边显示其具体的内容,比如用户id,地址什么的。

import React, { useEffect, useState } from 'react';

export default function HooksDemo() {
    const [users, setUsers] = useState([]);
    const [detail, setDetail] = useState("");
    useEffect(() => {
        fetch("https://api.randomuser.me/?nat=US&results=2") // 2 denotes that generating 2 users.
            .then(res => res.json())
            .then(json => setUsers(json.results));
    }, []);
    return users.length === 0 ? 'Loading!' :
        (
            <div style={{display: 'flex'}}>
                <ul style={{width: 300, cursor: 'pointer'}}>
                    {users.map(e =>
                        (<li key={e.email}>{e.name.first}---{e.dob.age}</li>))
                    }
                </ul>
                <div>
                    {detail}
                </div>
                {/* <div dangerouslySetInnerHTML={{__html: xxxhtmlstring}}></div> */}
            </div>
        )
}

假如这里的detail也需要fetch后复制。就会把useEffect里弄得挺臃肿。如果想把users这个state单独拿出来定义成一个hooks,就可以这样定义。

  新建hooks目录并在里面建立一个useUsers.js,注意使用use开头,其内容如下:

import {useState, useEffect} from 'react';

export default function useUsers() {
    const [users, setUsers] = useState([]);
    useEffect(() => {
        fetch("https://api.randomuser.me/?nat=US&results=2") // 2 denotes that generating 2 users.
            .then(res => res.json())
            .then(json => setUsers(json.results));
    }, []);

    return users; // array or object 
}

其实就是把users初始化及初始设置的部分搬过来。HooksDemo也跟着变:

import React, { useState } from 'react';
import useUsers from "../hooks/useUsers";

export default function HooksDemo() {
    const users = useUsers();
    const [detail] = useState("");
    return users.length === 0 ? 'Loading!' :
        (
            <div style={{display: 'flex'}}>
                <ul style={{width: 300, cursor: 'pointer'}}>
                    {users.map(e =>
                        (<li key={e.email}>{e.name.first}---{e.dob.age}</li>))
                    }
                </ul>
                <div>
                    {detail}
                </div>
                {/* <div dangerouslySetInnerHTML={{__html: xxxhtmlstring}}></div> */}
            </div>
        )
}

这样就演示了自定义useHooks的最基本的用法,感觉还不是很具体,后续有更新的话将补充。

原视频演示的是setDetail是在fetchuser后根据user的id再次fetch的,这是嵌套异步调用。我自己稍微改了下,变成换头像,大概效果就是点击列表的某一项,右边显示该用户的头像,但是detail的初始化没做好。

感兴趣的可以 参考源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值