将React类转换为功能组件



在我的旧存储库中,我使用类组件与以下CruiseListHeader组件代码作为示例(用于显示巡航按钮)。

import React from 'react';
import {getCruiseLines} from '../api/api'
import ListofShips from './ListofShips'


class CruiseListHeader extends React.Component {
constructor(props)  {
super(props)

//setting intial state for Cruise Headings and initialize cruiseHeaders as an empty array
this.state = {
cruiseHeaders: []
} 

//binding methods for setting up Cruise Line Headings
this.setUpCruiseLines = this.setUpCruiseLines.bind(this)
}  

componentDidMount() {
console.log('cdm')
this.setUpCruiseLines()
}

setUpCruiseLines()  {
console.log('getcruiselines')
getCruiseLines()
.then(res   =>  {

this.setState({
cruiseHeaders: res
})
})
}

render()    {
return  (
<React.Fragment>
{/* There will be Headings for all the Cruise Lines. */}
{/* Map the Cruiseline Headings for each Ship to display them on the page. I want to map ship, because I need each ship displayed in a List, when Cruise Line Heading is clicked. */}
<div className = "cruiseContainer">
{this.state.cruiseHeaders.map (ship =>  {

return (
<div key={ship.cruise_line}>
{/* ListofShips component needs cruise_line, because when user clicks on Cruise Line Heading button,
we need to fetch ships that belongs to that particular cruiseline. */}
{/* We need to render multiple ListofShips components, with one for each cruiseline */}
<ListofShips cruise_line={ship.cruise_line}></ListofShips>
</div>
)
})}
</div>      
</React.Fragment> 
)
}
} 
export default CruiseListHeader

请注意,这是所有相关的邮轮公司页面如下所示,其中有一个主要的邮轮公司。jsx组件与CruiselistHeader。将上面提到的JSX导入其中。

邮轮邮轮按钮页面

现在我想通过将这个React Class组件转换为一个Functional组件来开始更改。

这是我的CruiseListHeader作为一个功能组件,到目前为止。

请注意,ListofShips在这个新的存储库中现在被称为ShipsList。

import React, { useEffect, useState} from 'react'
import {getCruiseLines } from '../api/api'
import ShipsList from './ShipsList'
function CruiseListHeader() {
// Declare cruiseHeaders State variable 
const [cruiseHeaders] = useState({

})
useEffect (() =>    {
// Note: This was the original ComponentDidMount that took Binding this.setUpCruiseLines()
// Now it is coming from the CruiseListHeader.js useEffect to the DOM    
}
)

return  (
<>
<div>    
<div key={ship.cruise_line}>
<ShipsList cruise_line={ShipsList.cruise_line}></ShipsList>            
</div>
</div>    
</>
)
}
export default CruiseListHeader

我想了解的是,功能组件如何处理我的api状态,绑定和映射,我以前在我的类组件中使用?

如果有人知道我该如何处理,那将是非常有价值的帮助,谢谢。

你忽略了setter的状态,你的useState行应该是:

const [cruiseHeaders, setCruiseHeaders] = useState({});

然后使用setCruiseHeaders函数来设置状态:

useEffect (() => {
getCruiseLines()
.then(res => {
setCruiseHeaders({
cruiseHeaders: res
})
});
}, []); // Make sure to also pass an array here, or you'll be triggering this effect on every render
作为题外话,可能意味着将状态值初始化为数组而不是对象:
const [cruiseHeaders, setCruiseHeaders] = useState([]);

自"巡航标题"起;原始代码中的数据是一个数组。

import React, { useEffect, useState} from 'react'
import {getCruiseLines } from '../api/api'
import ShipsList from './ShipsList'
function CruiseListHeader() {
// Declare cruiseHeaders variable and set it's array using useState 
const [cruiseHeaders, setCruiseHeaders] = useState([]);    

// Note: This was the original ComponentDidMount that took Binding this.setUpCruiseLines()
// Now it is coming from CruiseListHeader.jsx useEffect to the DOM    
useEffect (() => {
getCruiseLines()
.then(res => {
setCruiseHeaders({
cruiseHeaders: res
})
});
}, []); // Make sure to also pass an array here, or you'll be triggering this effect on every render
return  (
<>
{/* <div className = "cruiseContainer"> I don't think I need this because I am using Tailwind CSS*/}
{/* When I use Sass in my next final repo I may not need a div either */}
{cruiseHeaders.map (ship => {
// return  ( Do not need return here, I think
<div key = {ship.cruise_line}>
{/* ListofShips component needs cruise_line, because when user clicks on 
Cruise Line Heading button, we need to fetch ships that belongs to that particular 
cruiseline. */}
{/* We need to render multiple ShipsList components, with one for each cruiseline */}
<ShipsList cruise_line={ship.cruise_line}/>
{/* </ShipsList>  I think I don't I need this closing tag*/}
</div>
// ) I think, I do not need return closing bracket here
})}
{/* </div> I think, I do not need closing div from cruiseContainer here*/}
</>
)
}
export default CruiseListHeader