У меня есть два компонента 1. Фильтр и 2. Данные.
Я ввел оба компонента в файл main.js
1.Main.js
render() {
return (
<div className = {classes.Main}>
<Filter />
<DataComponent />
</div>
);
}
2. компонент фильтра
В фильтре компонент имеет два раскрывающихся списка: 1. Цвет и 2. класс. на основе раскрывающегося списка необходимо передать данные из компонента фильтра в компонент данных
import React from 'react';
const Filter = (props) => {
return (
<div>
<ul>
<li className = {classes.displayInline} >
<select name='color' onChange = {this.handleChangeEvent} >
<option value='0'>Select</option>
<option value='1'>red</option>
<option value='2'>blue</option>
</select>
</li>
<li className = {classes.displayInline} >
<select name='class' >
<option value='0'>Select Class</option>
<option value='1'>first</option>
<option value='2'>Second</option>
<option value='3'>Third</option>
<option value='4'>Fourth</option>
</select>
</li>
</ul>
</div>
);
}
export default Filter;
3. компонент данных
import React, { Component } from 'react';
class DataComponent extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
content: [],
}
}
componentDidMount() {
fetch("url")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
/**** data getting from api is pushed to content ****/
content.push(items);
});
return (
/**** render part ***/
)
}
}
export default DataComponent;
Необходимо получить раскрывающиеся значения от компонента фильтра к компоненту данных.
У меня новичок в системе reactjs.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Мой первый инстинкт - сказать, что вы должны просто объединить два компонента в один.
Компоненты обладают способностью сохранять состояние не просто так. Нет особого смысла использовать функциональный компонент, а затем разбивать его состояние на отдельный компонент.
Наличие content.push в вашей функции render также немного странно для React. Ваша функция render должна нести единоличную ответственность за рендеринг, ничего больше. Если вы хотите что-то сделать в своей функции render, создайте обработчик.
Вот как я бы создал ваш класс фильтра. Имейте в виду, что этот код написан без тестирования, поэтому он может потребовать некоторых настроек, но общая структура есть.
import React from 'react'
export default class Filter extends React.Component {
constructor (props) {
super(props)
this.state = {
items: [],
content: [],
isLoaded: false,
error: null,
selectedColorFilter: null,
selectedClassFilter: null
}
//There's probably a better way to refactor this so it's just one handler, but I'm just using two for illustrative purposes here.
this.handleColorFilterChange = this.handleColorFilterChange.bind(this)
this.handleClassFilterChange = this.handleClassFilterChange.bind(this)
}
componentDidMount () {
fetch('url')
.then((res) => {
return res.json()
})
.then((data) => {
this.setState({
isLoaded: true,
items: data
})
})
.catch((error) => {
this.setState({
isLoaded: false,
error: error
})
})
}
handleColorFilterChange (event) {
//this may not be right, but I think it'll pick up the right value, may have to change it
this.state.selectedColorFilter = event.target.value
}
handleClassFilterChange (event) {
//again, might not be right, but I think it'll grab the value
this.state.selectedClassFilter = event.target.value
}
renderColorFilter () {
<li className = {classes.displayInline} >
<select name='color' onChange = {this.handleColorFilterChange} >
<option value='0'>Select</option>
<option value='1'>red</option>
<option value='2'>blue</option>
</select>
</li>
}
renderClassFilter () {
<li className = {classes.displayInline} >
<select name='class' onChange = {this.handleClassFilterChange} >
<option value='0'>Select Class</option>
<option value='1'>first</option>
<option value='2'>Second</option>
<option value='3'>Third</option>
<option value='4'>Fourth</option>
</select>
</li>
}
render () {
return (
<div>
<ul>
{this.renderColorFilter()}
{this.renderClassFilter()}
</ul>
</div>
)
}
}
Надеюсь, это имеет смысл.
In Filter Component
handleChangeEvent = (event) => {
if (typeof this.props.selectedValueHandler !== 'undefined'){
this.props.selectedValueHandler(event.target.value);
}
}
In Main Component
В вашем основном файле вам нужно передать функцию selectedValueHandler как
опора для компонента фильтра, который будет использоваться как компонент фильтра обратного вызова
изнутри компонента Filter по выбору.
Выбранное значение затем можно передать в Data Componennt.
constructor() {
this.state = {
selectedValue: null
}
}
selectedValueHandler = (selectedValue) => {
this.setState({
selectedValue
})
}
render() {
const { selectedValue } = this.state;
return (
<div className = {classes.Main}>
<Filter selectedValueHandler = {this.selectedValueHandler}/>
<DataComponent selectedValue = {selectedValue} />
</div>
);
}
In your Data Component
Вы можете напрямую получить доступ к выбранному значению в компоненте данных, используя
class DataComponent extends Component {
render() {
const { selectedValue } = this.props;
...
}
}
или если вы хотите сделать его частью состояния компонента данных.
class DataComponent extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
content: [],
selectedValue: this.props.selectedValue
}
}
componentwillreceiveprops(nextProps) {
if (this.state.selectedValue !== nextProps.selectedValue) {
this.setState({
selectedValue: nextProps.selectedValue
})
}
}
render() {
const { selectedValue } = this.state;
...
}
}
Зависит от вашего варианта использования.
@karthick, функция конструктора вызывается только один раз в жизненном цикле, рекомендуется использовать ее непосредственно при рендеринге или использовать другой компонент для обработки. Я обновил ответ для справки. :)
Остерегайтесь использования componentWillReceiveProps, так как это устаревшая функция. Чтобы быть уверенным в завтрашнем дне, вам следует рассмотреть альтернативный дизайн.
Насколько мне известно, есть 2 способа решения этой проблемы:
Использование Redux для управления общим состоянием вашего приложения. Пожалуйста, посмотрите пример на сайте Redux (https://redux.js.org/basics/exampletodolist)
Использование родительского состояния
В вашем Main.js инициализирует состояние для содержания изменения в его дочернем Фильтр
constructor(props) {
super(props);
this.state = {
value: null, //used to contains your dropdown value
}
this.getDropdownData = this.getDropdownData.bind(this);
}
и функция для получения значения из фильтра
getDropdownData(value){
this.setState({
value : myvalue
});
}
затем передайте функцию getDropdownData() для получения данных в Фильтр, а value в состоянии - в Компонент данных
render() {
return (
<div className = {classes.Main}>
<Filter getDropdownData = {this.getDropdownData}/>
<DataComponent dropdownValue = {this.state.value}/>
</div>
);
}
В Filter.js
Вызов переданной функции в this.handleChangeEvent с помощью this.props.getDropdownData(input_dropdown_value)
Не забываем привязать this.handleChangeEvent в constructor()
this.handleChangeEvent = this.handleChangeEvent.bind(this)
Наконец
Используя раскрывающееся значение в Компонент данных, вызывая this.props.dropdownValue
Надеюсь, это поможет тебе
@anushul .: спасибо, я могу получить значение от фильтра до основного компонента. но я не могу получить selectedValue в компоненте данных. используя переменную selectedValue, я пытаюсь получить результат в компоненте данных в функции конструктора, это правильно?