将此 react class 组件更改为 react hooks
Change this react class component into react hooks
我正在观看此视频中的 MERN Stack 教程 MERN。
在 1:41:16 - 1:47:01 部分
我正在尝试将所有内容转换为反应挂钩,并且一切顺利,直到 exercise-list component
这是我将其转换为 react-hook 组件时的代码。
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import axios from 'axios'
const Exercise = item => {
<tr>
<td>{item.exercise.username} </td>
<td>{item.exercise.description} </td>
<td>{item.exercise.duration} </td>
<td>{item.exercise.date.substring(0,10)} </td>
<td><Link to={"/edit/" + item.exercise._id}> Edit</Link> |
<a href="#" onClick={e => {item.handledeleteExercise(item.exercise._id)}}> delete </a>
</td>
</tr>
}
function Exercises_List(props) {
const [deleteExercise,setdeleteExercise] = useState()
const [exercises,setexercises] = useState([])
useEffect(() => {
axios.get('http://localhost:4500/exercises/')
.then(res => {
setexercises([...exercises,res.data])
})
.catch(err => console.log(err))
},[])
const handledeleteExercise = (id) => {
axios.delete('http://localhost:4500/exercises'+id)
.then(res => console.log(res.data));
const filtered = exercises.filter((el) => el._id !== id)
setexercises(filtered)
}
const exerciseList = () => {
return exercises.map(currentexercise => {
return <Exercise
exercise={currentexercise}
handledeleteExercise={e => handledeleteExercise(e)}
key={currentexercise._id}></Exercise>
})
}
return (
<div>
<h3> Logged Exercises</h3>
<table className="table">
<thead className="thead-light">
<tr>
<th>Username </th>
<th>Description </th>
<th>Duration </th>
<th>Date </th>
<th>Actions </th>
</tr>
</thead>
<tbody>
{exerciseList()}
</tbody>
</table>
</div>
)
}
export default Exercises_List
唯一让我困惑的是const [deleteExercise,setdeleteExercise] = useState()
正如你在 1:41:22 的视频中看到的那样..我很困惑我应该如何使用 deleteExercise 将它转换为 react-hooks.. 我试过这样的东西
deleteExercise = e => {
....
}
``` But I know that is out of the rules in react hooks...Another thing I look at here is this part of
useEffect(() => {
axios.get('http://localhost:4500/exercises/')
.then(res => {
setexercises({...exercises:res.data})
})
.catch(err => console.log(err))
},[])
once I show this in my output
{exerciseList()}
它给我这样的错误TypeError: exercises.map is not a function
我想我在这里错过了一个想法......我也对 edit-exercises.component
的部分感到困惑,其中它在 1:43:32 的部分传递了 props.match.params.id
..
伙计们,我快死了..我非常想制作简单的全栈网站,但我就是做不到哈哈...教程和我的文档学习特别是更新和文档令人困惑。
我无法解释这一切,对此我深表歉意...我想在这里解决的是将其转换为 react-hooks,因为 react class 组件在我的本性中并不是很有用。
我认为你的代码失败是因为:
setexercises({...exercises:res.data})
该语句在 exercises
变量中存储 一个对象 ,并且对象没有 map
方法。
(实际上,我认为该语句不是有效语法:您不能在也有值的 属性 名称前放置三个点。您可以这样做:({ ...res.data })
或这个({ exercises: res.data })
——尽管两者仍然会以相同的方式中断,因为它们都存储一个对象而不是一个数组。但这些至少是有效的ES6语法。)
我怀疑更大的问题是你没有正确考虑你的数据。
- 你有一个练习列表
- 您希望能够在该列表中添加和删除项目
很明显你只需要一个数组。那个数组是你应该使用 React 的 useState
钩子存储的:
let [ exercises, setExercises ] = React.useState([])
因此:exercises
是列表(具有 map
方法的数组),而 setExercises
让您可以完全覆盖该数组。请注意最后一块:useState 挂钩提供的唯一工具 是一个破坏整个列表 的工具。这意味着您的“添加”和“删除”操作必须仅使用该工具来完成它们的任务。
所以,你必须完成这个函数的实现:
function addExercise( newExercise ) {
/*
STEP 1: calculate fresh array that contains
all the current exercises plus newExercise.
*/
let newList = [/* TODO */]
/*
STEP 2: overwrite current list using the
only tool provided by useState. This updates
the data *and* immediately re-renders the
component with the new data.
*/
setExercises(newList)
}
同样的想法适用于从列表中删除练习:
function removeExercise( exerciseToRemove ) {
/*
STEP 1: calculate fresh array that contains
all the current exercises minus exerciseToRemove.
*/
let newList = [/* TODO */]
/*
STEP 2: overwrite current list using the
only tool provided by useState.
*/
setExercises(newList)
}
当您 API 调用 returns:
时,同样的工具也是您更新列表的方式
useEffect(() => {
axios.get('http://localhost:4500/exercises/')
// this assumes that res.data is an array
.then(res => setExercises(res.data))
.catch(err => console.log(err))
}, [])
此外:您的练习组件可能无法解析。包裹body的花括号需要是圆括号,或者body里面需要一个return
语句:
// bad!
const MyComp = props => { <div> thing </div> }
// good
const MyComp = props => ( <div> thing </div> )
// also good
const MyComp = props => { return (<div> thing </div>) }
我正在观看此视频中的 MERN Stack 教程 MERN。
在 1:41:16 - 1:47:01 部分
我正在尝试将所有内容转换为反应挂钩,并且一切顺利,直到 exercise-list component
这是我将其转换为 react-hook 组件时的代码。
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import axios from 'axios'
const Exercise = item => {
<tr>
<td>{item.exercise.username} </td>
<td>{item.exercise.description} </td>
<td>{item.exercise.duration} </td>
<td>{item.exercise.date.substring(0,10)} </td>
<td><Link to={"/edit/" + item.exercise._id}> Edit</Link> |
<a href="#" onClick={e => {item.handledeleteExercise(item.exercise._id)}}> delete </a>
</td>
</tr>
}
function Exercises_List(props) {
const [deleteExercise,setdeleteExercise] = useState()
const [exercises,setexercises] = useState([])
useEffect(() => {
axios.get('http://localhost:4500/exercises/')
.then(res => {
setexercises([...exercises,res.data])
})
.catch(err => console.log(err))
},[])
const handledeleteExercise = (id) => {
axios.delete('http://localhost:4500/exercises'+id)
.then(res => console.log(res.data));
const filtered = exercises.filter((el) => el._id !== id)
setexercises(filtered)
}
const exerciseList = () => {
return exercises.map(currentexercise => {
return <Exercise
exercise={currentexercise}
handledeleteExercise={e => handledeleteExercise(e)}
key={currentexercise._id}></Exercise>
})
}
return (
<div>
<h3> Logged Exercises</h3>
<table className="table">
<thead className="thead-light">
<tr>
<th>Username </th>
<th>Description </th>
<th>Duration </th>
<th>Date </th>
<th>Actions </th>
</tr>
</thead>
<tbody>
{exerciseList()}
</tbody>
</table>
</div>
)
}
export default Exercises_List
唯一让我困惑的是const [deleteExercise,setdeleteExercise] = useState()
正如你在 1:41:22 的视频中看到的那样..我很困惑我应该如何使用 deleteExercise 将它转换为 react-hooks.. 我试过这样的东西
deleteExercise = e => {
....
}
``` But I know that is out of the rules in react hooks...Another thing I look at here is this part of
useEffect(() => {
axios.get('http://localhost:4500/exercises/')
.then(res => {
setexercises({...exercises:res.data})
})
.catch(err => console.log(err))
},[])
once I show this in my output
{exerciseList()}
它给我这样的错误TypeError: exercises.map is not a function
我想我在这里错过了一个想法......我也对 edit-exercises.component
的部分感到困惑,其中它在 1:43:32 的部分传递了 props.match.params.id
..
伙计们,我快死了..我非常想制作简单的全栈网站,但我就是做不到哈哈...教程和我的文档学习特别是更新和文档令人困惑。
我无法解释这一切,对此我深表歉意...我想在这里解决的是将其转换为 react-hooks,因为 react class 组件在我的本性中并不是很有用。
我认为你的代码失败是因为:
setexercises({...exercises:res.data})
该语句在 exercises
变量中存储 一个对象 ,并且对象没有 map
方法。
(实际上,我认为该语句不是有效语法:您不能在也有值的 属性 名称前放置三个点。您可以这样做:({ ...res.data })
或这个({ exercises: res.data })
——尽管两者仍然会以相同的方式中断,因为它们都存储一个对象而不是一个数组。但这些至少是有效的ES6语法。)
我怀疑更大的问题是你没有正确考虑你的数据。
- 你有一个练习列表
- 您希望能够在该列表中添加和删除项目
很明显你只需要一个数组。那个数组是你应该使用 React 的 useState
钩子存储的:
let [ exercises, setExercises ] = React.useState([])
因此:exercises
是列表(具有 map
方法的数组),而 setExercises
让您可以完全覆盖该数组。请注意最后一块:useState 挂钩提供的唯一工具 是一个破坏整个列表 的工具。这意味着您的“添加”和“删除”操作必须仅使用该工具来完成它们的任务。
所以,你必须完成这个函数的实现:
function addExercise( newExercise ) {
/*
STEP 1: calculate fresh array that contains
all the current exercises plus newExercise.
*/
let newList = [/* TODO */]
/*
STEP 2: overwrite current list using the
only tool provided by useState. This updates
the data *and* immediately re-renders the
component with the new data.
*/
setExercises(newList)
}
同样的想法适用于从列表中删除练习:
function removeExercise( exerciseToRemove ) {
/*
STEP 1: calculate fresh array that contains
all the current exercises minus exerciseToRemove.
*/
let newList = [/* TODO */]
/*
STEP 2: overwrite current list using the
only tool provided by useState.
*/
setExercises(newList)
}
当您 API 调用 returns:
时,同样的工具也是您更新列表的方式useEffect(() => {
axios.get('http://localhost:4500/exercises/')
// this assumes that res.data is an array
.then(res => setExercises(res.data))
.catch(err => console.log(err))
}, [])
此外:您的练习组件可能无法解析。包裹body的花括号需要是圆括号,或者body里面需要一个return
语句:
// bad!
const MyComp = props => { <div> thing </div> }
// good
const MyComp = props => ( <div> thing </div> )
// also good
const MyComp = props => { return (<div> thing </div>) }