React установка переменных состояния в функции карты - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь настроить приложение для реагирования, в котором отображается список кнопок, пользователь может нажать кнопку и попасть на страницу с информацией о стране. Я создаю кнопки программно, используя функцию .map. Я использую базу данных SQL для хранения названий стран и информации о странах, а затем вызываю маршрут flask, чтобы вытащить данные в мое приложение для реагирования. Для этого я использую функцию async.

Это процесс, который я хотел бы осуществить: я установил некоторые переменные с отслеживанием состояния в своем приложении. js основной компонент маршрутизатора. Затем я передаю в качестве реквизита свои функции setState своему компоненту с помощью кнопок и функции .map. Для каждой кнопки есть возможность установить состояние переменных в компоненте App. js. Затем я бы установил переменные в App. js на значения, связанные с нажатой кнопкой. Оттуда я мог передать эти переменные с сохранением состояния в компонент моей страницы для отображения. в итоге получите undefined. Похоже, что undefined может быть последним элементом набора данных, поскольку я уже получил Зимбабве в качестве результата ранее. Вот мой код для приложения. 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>
        )

}

Вот мой код для компонента страны

export default function Country(props) {

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

}

Большое спасибо за помощь!

1 Ответ

1 голос
/ 06 мая 2020

Я не буду точно отвечать на ваш вопрос, но я предлагаю некоторый рефакторинг и, возможно, это решит вашу проблему. компоненты (я добавил приятную обработку получения изменения статуса). Здесь вы будете отображать правильные маршруты только в том случае, если данные получены успешно.

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);) Извините, если это не решит ваши проблемы, но я надеюсь, что он содержит хотя бы несколько хороших идей для рефакторинга;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...