#reactjs
#reactjs
Вопрос:
Итак, я совсем новичок в веб-разработке последние пару дней. Я работаю на c и не могу разобраться во всех принципах reactjs. У меня есть 2 класса. Дочерний класс с именем JobAd должен отображать некоторую информацию, которую он получил из props.
export default class JobAd extends Component {
constructor(props) {
super(props);
this.state ={
index: props.index,
id: props.jobId,
name: props.name,
description: props.description,
location: props.location,
adress: props.adress,
alreadyApplied: props.alreadyApplied,
open: false,
// toggleJob: props.toggleJob,
};
this.toggleJob = props.toggleJob;
}
render() {
return (
<div className={`${styles.jobAd} d-flex` "job " (this.state.open ? 'open': '')} key={this.state.index} onClick={() => this.toggleJob(this.state.index)}>
<div className={`${styles.jobTitle}`}>
{this.state.location} - {this.state.name}
</div>
<div className={`${styles.jobDetails}`}>
<div className={`${styles.jobDescription}`}> {this.state.description}</div>
<div className={`${styles.jobAdress}`}>{this.state.adress}</div>
<ApplyButton jobId= {this.props.id} alreadyApplied = {this.props.alreadyApplied}/>
</div>
</div>
)
}
}
Второй класс запрашивает базу данных MongoDB и создает объекты jobAd, заполняя их информацией, полученной из базы данных.
class JobExplorer extends React.Component
{
...
result.data.jobs.forEach(job => {
var find = job.employees.find(obj => obj === userId);
if (!(find === undefined)) {
alreadyApplied = true;
}
var toPush = new JobAd ({
index: i,
id:job._id,
description:job.description,
name:job.name,
location:job.locationName,
adress:job.locationAdress,
alreadyApplied:alreadyApplied,
open:false,
toggleJob: this.toggleJob.bind(this)
});
jobList2.push(toPush);
console.log("look");
console.log(jobList2)
});
this.setState({
jobList: jobList2
})
this.setState({
error: null,
jobs: result.data.jobs
});
...
render()
{
console.log("look2");
console.log(this.state.jobList);
return (
<div><Navigation />
{this.state.jobList}
</div>
);
}
Но я столкнулся со следующей ошибкой, для которой я не могу найти исправление.
Ошибка: Объекты недопустимы как дочерние элементы React (найдено: объект с ключами {props, context, refs, updater, state, toggleJob}). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив.
Как я должен создавать экземпляры этих объектов, чтобы я мог отображать их, используя «архитектуру», которую я написал. Есть ли фундаментальный недостаток в моих классах?
Комментарии:
1. Возможно, вам захочется обратиться к документации react, чтобы узнать, как отображать списки, см.: React — Lists
Ответ №1:
Приведенный ниже фрагмент не работает, потому что new
вернет object (this)
не компонент react.
Итак, вместо
var toPush = new JobAd({
index: i,
id: job._id,
...
});
jobList2.push(toPush);
вы можете сделать это
var toPush = <JobAd
index={i}
id={job._id}
...
/>;
Приведенный выше фрагмент работает, потому что <JobAd ... />
преобразуется в React.createElement(JobAd, ... )
. Тем не менее, вы все равно не должны делать это так. поскольку есть много лучших способов сделать это. одним из них является:
сохраните только данные в joblist
, а затем отобразите список данных в JobAd
компоненте
как показано ниже:-
render(){
return this.state.joblist.map((job, i) => (
<JobAd
key={job._id}
index={i}
...
/>
));
}
Ключ — это действительно важная вещь. Читайте об этом:https://reactjs.org/docs/lists-and-keys.html
Вещи, которые можно было бы улучшить:-
-
Не копируйте реквизиты в состоянии, как вы делаете в
JobAd
классе, вместо этого непосредственно визуализируйте реквизиты. -
Не вызывайте setState дважды, как в
JobExplorer
. вы могли бы установить все ключи вsetState
одновременно. поскольку это привело бы к отображению компонента дважды.
Предложения:-
- Вам следует избегать использования
var
, поскольку это может вызвать некоторые проблемы здесь. - поскольку вы только начинающий, попробуйте сначала использовать функциональный компонент. их гораздо проще понять
Ответ №2:
Похоже, у вас неправильное представление о состоянии / реквизитах в React и веб-разработке. Это очень нормально; сначала я изучил python и Java, и многие учебные пособия, похоже, предполагают, что люди просто уже знают это.
«Состояние» в общем случае относится к переменным, содержащим / ссылающимся на значения, которые могут изменяться без обновления страницы в вашем приложении. Если вы знаете, что значение не изменится, его не нужно сохранять в состоянии. Сохранение ее в обычной переменной — это именно то, что вы должны сделать.
«Реквизит» — это просто другое слово для аргументов, которые передаются компонентам React. На самом деле это еще не все, но, как новичку, это все, что вам нужно знать на данный момент.
Итак, в вашем job add такие вещи, как имя, адрес, задания, описание, не должны переходить в состояние, потому что они не изменятся в результате взаимодействия с пользователем или по любой другой причине, если не изменятся базовые данные, из которых они загружены, но тогда это будет обрабатываться не React, а API, из которого ваше приложение получает данные. Они должны просто отображаться, поэтому обращайтесь к ним следующим образом.props.address в вашем методе рендеринга. Значение для open, однако, должно быть в состоянии, потому что это определенно может измениться.
Что касается ошибки, похоже, вы неправильно вызываете JobAd. Вам нужно использовать синтаксис <Job Ad/>
, а не new JobAd
…это не будет работать в React.
Я бы рекомендовал выполнить руководство, чтобы разобраться с основами.