1.当param发送变化,副作用的依赖监控到变化,则发起请求得到列表数据,但我们用到列表数,所以操作列表数据的hook也定义在此页面,在List组件中该怎么得到父组件中拿到的数据呢,这就需要用到状态提升。随后将其中的数据拿到父组件中,然后通过React的prop传值传给子组件进行使用,在函数子组件中解构给子组件内部进行使用。
import { useState, useEffect } from "react"
export const SearchPanle = () => {
// input
const [param, setParam] = useState({
name: '',
personId: ''
})
// select
const [users, setUsers] = useState([])
// list
const [list, setList] = useState([])
// param变化的时候请求项目列表的接口 加一个依赖 意思是param改变的时候进行获取接口
useEffect(() => {
//请求接口
fetch('').then(async response => {
if (response.ok) {
// json()返回一个被解析为JSON格式的promise对象
setList(await response.json())
}
})
}, [param])
return <form>
<div>
{/* 相当于 setParam(Object.assign({},param,{name:e.target.value})) */}
<input type="text" value={param.name} onChange={e => setParam({
...param,
name: e.target.value
})} />
<select value={param.personId} onChange={e => setParam({
...param,
personId: e.target.value
})}>
<option value={''}>负责人</option>
{
users.map(user => <option value={user.id}>{user.name}</option>)
}
</select>
</div>
</form>
}
解构传递给子组件进行使用
export const SearchPanle = ({param,setParam}) => {
//具体内容...
2.react的项目占据了3000端口,将json-server端口设置为3001,在script里添加--port3001。
3.fetch()中如果将请求地址写死,则当后端完成接口后我们需要一个个更改,解决方案是在根目录下建立了两个文件:
在index.jsx里面定义fetch请求的地址,放在fetch中使用,
const apiUrl =process.env.REACT_APP_API_URL
// 请求接口
fetch(`${apiUrl}/projects`).then(async response => {
if (response.ok) {
// json()返回一个被解析为JSON格式的promise对象
setList(await response.json())
当我们运行npm start命令时,说明是开发环境,webpack会读取.env.development中的REACT_APP_API_URL,而运行npm run build线上打包时,webpack则会读取.env中的变量。
4.后台返回的数据中并没有我们想要的usersname,也就是说我们需要自己对照id找到相应的项目name
//通过json-server返回的数据类型
{
"id": 4,
"name": "王文静"
}
],
"projects": [
{
"id": 1,
"name": "骑手管理",
"personId": 1,
"organization": "外卖组",
"created": 1604989757139
},
// 找到projects(具体项目)中的personid与选择负责人的users.id相同的那一项的name
<td>{users.find(users => users.id === project.personId)?.name || '未知'}</td>
?的意思是当name前面的表达式是undefined时,整个表达式会undefined,不会报错,我们让其默认值为"未知"
5.注意每个map渲染的列表都需要独特的key属性。
6.如果查询条件像这样...?name=&id=2,后台可能未对数据进行处理,不知道该返回所有还是name未空的项,我们引入一个函数对后台值为空的数据进行处理。
// 排除value为0的情况 !!的意思是转换为布尔值
export const isFalsy = (value) => value === 0 ? false : !value
// 该函数用来删除数据里值是空的那一项
export const cleanObject = (object) => {
// 直接对对象进行操作是不好的,用拓展运算符拷贝一份新数据result
// 思路是对result进行修改后再return出去
const result = { ...object }
// 拿到传进来的对象的所以键名 然后用foreach遍历所有键名(key)
Object.keys(result).forEach(key => {
//拿到该对象对应键名的值 定义为value
const value = object[key]
// 判断value是否存在 如果不存在 则删除该键
// 有时候value=0时也是有效数据 故直接判断if(!value)会忽略value为0的情况
// 所以定义一个函数先排除value为0的情况
if(isFalsy(value)){
delete result[key]
}
})
return result
}
如果查询条件过多,写入必定很繁琐,用yarn add qs进行处理,将查询条件传入先前定义好的去除值为空的函数
fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(param))}`).then(async response => {
if (response.ok) {
// json()返回一个被解析为JSON格式的promise对象
setList(await response.json())
}
})
}, [param])