【问题标题】:React setting Stateful variables in map function在地图函数中反应设置有状态变量
【发布时间】:2020-08-21 14:20:05
【问题描述】:

我正在尝试设置一个显示按钮列表的反应应用程序,用户可以按下按钮并被带到包含有关国家/地区信息的页面。我正在使用.map 函数以编程方式创建按钮。我正在使用 SQL 数据库来存储国家/地区名称和有关国家/地区的信息,然后调用烧瓶路由将数据提取到我的反应应用程序中。为此,我使用了async 函数。

这是我希望发生的过程: 我在我的 App.js 主路由器组件中设置了一些有状态变量。然后,我将 setState 函数作为道具传递给带有按钮和 .map 函数的组件。对于每个按钮,都可以选择在 App.js 组件中设置变量的状态。然后,我会将 App.js 中的变量设置为与单击的按钮关联的值。从那里,我可以将这些状态变量传递给我的国家页面组件进行显示。

实际发生的情况: 我将道具传递给我的国家组件,期望一个国家和国家的详细信息随之传递,但我最终得到undefined。看起来 undefined 可能是数据集的最后一个元素,因为我之前得到了津巴布韦的结果。这是我的 App.js 路由器代码:

export default function App() {

const [cname, setCName] = useState('')
const [pdf, setPdf] = useState('')
const [details, setDetails] = useState('')

  return (
    <div className="App">
      <BrowserRouter>
        {/* <Route exact path="/" component = { Home }/> */}
        <Route path="/cia" component = {(props) => <CIALanding {...props} setCName={setCName} setPdf={setPdf} setDetails={setDetails}/>}/>
        <Route path="/country" component={(props) => <Country {...props} setCName={setCName} details={details} cname={cname}/>}/>
        <Route path="/countrypage" component={CountryPage}/>          
      </BrowserRouter>
    </div>
  );
}

这是我的登录页面的代码(使用.map 函数)

export default function CIALanding(props) {


    const [countriesList, setCountriesList] = useState([])

    const getCountries = async () => {
        const response = await fetch('http://127.0.0.1:5000/countries');
        const data = await response.json();
        setCountriesList(data['country_list'].map((country) => {return (
            <Link to={{pathname:'/country',
            }}>
            <Country cname1={country[0]} details={country[2]} setCName={props.setCName}>{country[0]}</Country>
            </Link>
        )}))
    }

    useEffect(() => {
        getCountries()
    },[])
        return (
            <div>
            {countriesList}
            </div>
        )

}

这是我的 Country 组件代码

export default function Country(props) {

    return (
        <div>
         {console.log(props.cname)}
        <Button onClick={props.setCName(props.cname1)}>{props.cname1}</Button>
        </div>
    )

}

非常感谢您的帮助!

【问题讨论】:

    标签: reactjs jsx stateful


    【解决方案1】:

    我不会完全回答您的问题,但我建议进行一些重构,也许这会解决您的问题。

    首先,我会将获取代码移至 App 组件,这将允许组件更轻松地访问这些数据(我添加了一些很好的获取状态更改的处理)。只有在成功获取数据的情况下,您才会在此处呈现正确的路由。

    const App = () => {
      const [status, setStatus] = useState(null);
      const [countries, setCountries] = useState([]);
    
      const getCountries = async () => {
        setStatus('loading');
    
        try {
          const response = await fetch('http://127.0.0.1:5000/countries');
          const data = await response.json();
    
          setCountriesList([...data['country_list']]);
          setStatus('success')
        } catch (error) {
          setSatus('error');
        }
      }
    
      useEffect(() => {
        getCountries();
      }, [])
    
      if (!status || status === 'error') {
        return <span>Loading data error</span>
      }
    
      if (status === 'loading') {
        return <span>Loading...</span>
      }
    
      return (
        <div className="App">
          <BrowserRouter>
            <Route path="/cia" component={(props) => <CIALanding {...props} countries={countries} />
            <Route path="/country/:countryId" component={(props) => <Country {...props} countries={countries} />    
          </BrowserRouter>
        </div>
      );
     }
    

    第二件事 - 要显示正确的国家页面,您不需要将任何数据设置为状态,只需设置路由 /country/:countryId 和正确路径的链接,其中 countryId 可以是唯一的国家标识符作为数字或代码.通过这样的设置,组件中只需要数据是国家/地区数组,加载哪个国家/地区由路由决定

    登陆组件会很简单(你绝对不应该让 React 组件保持状态,只有数据)

    const CIALanding = ({countries}) => (
      <div>
        {
          countries.map(({countryName, countryId}) => (
            <Link to={`/country/${countryId}`}>{countryName}</Link>
          ))
        }
      </div>
    )
    

    所以现在我们有很好的国家列表和正确的链接。然后国家页面会知道参数countryId要显示哪些数据

    const Country = ({match, countries}) => {
      //match object is passed by Route to this component and inside we have params object with countryId
      const {countryId} = match.params;
      const country = countries.find(country => country.countryId === countryId);
    
      if (country) {
        return (
          <div>
            Show info about selected country
          </div>
        );
      }
    
      return (
        <div>
          Sorry, cannot find country with id {countryId}
        </div>
      )
    }
    

    您可以通过单击链接访问正确的国家/地区页面,另外还可以通过在浏览器中输入路径,例如.../country/ENG(我不知道您的数据结构,因此请记住为 countryId 使用正确的数据);) 抱歉,如果这不能解决您的问题,但我希望它至少包含一些重构的好主意;)

    【讨论】:

    • 谢谢,太棒了!
    猜你喜欢
    • 1970-01-01
    • 2020-02-22
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多