仅学习React并遇到问题。我有一个选择器,可以选择车辆的年份/品牌/型号。但是,如果要更改年份,我希望它重置品牌和型号,或者如果更改品牌,我只是希望重置型号,以便将这些选项状态设置为null,从而取消选中ui。
但是,问题是我不知道如何使其他人可以使用组件的状态。我认为解决方案可能像使用year的onChange函数一样简单,然后将使用make / model的状态并将其重置为null,尽管没有year.js无法知道其他2个状态,这是不可能的。 / p>
希望您能理解我在说什么。这是代码。 Year.js
import React, { Component } from 'react';
import '../CSS/App.css';
const vehicleYear = [
{id:1,label:"2019",href:"#"},
{id:2,label:"2018",href:"#"},
{id:3,label:"2017",href:"#"},
{id:4,label:"2016",href:"#"},
{id:5,label:"2015",href:"#"},
{id:6,label:"2014",href:"#"}
];
class Year extends Component {
constructor(props){
super(props);
this.state = {
year: null,
}
}
createYearList = () => {
let listItems = [];
for (let i = 0; i < vehicleYear.length; i++) {
listItems.push(
<li className={`list ${this.state.year === vehicleYear[i].id ? "active" : ""}`} onClick={(e) => {
this.yearClick(e, vehicleYear[i].id, vehicleYear[i].label)
}}>
<a href={vehicleYear[i].href}>{vehicleYear[i].label}</a>
</li>
);
}
return listItems;
};
yearClick = (e, id, label) => {
let state = this.state;
state.year = id;
this.setState(state);
console.log(this.state);
console.log(this.props.year);
};
render() {
return (
<div>
{this.createYearList()}
</div>
)
}
}
export default Year;
Make.js
import React, { Component } from 'react';
import '../CSS/App.css';
const vehicleMake = [
{id:1,label:"POLARIS",href:"#"},
{id:2,label:"CAN_AM",href:"#"},
{id:3,label:"YAMAHA",href:"#"},
{id:4,label:"SUZUKI",href:"#"},
{id:5,label:"ARCTIC-CAT",href:"#"}
];
class Make extends Component {
constructor(props){
super(props);
this.state = {
make: null
}
}
createMakeList = () => {
let listItems = [];
for(let i = 0; i < vehicleMake.length; i++){
listItems.push(
<li className={`list ${this.state.make === vehicleMake[i].id ? "active" : ""}`} onClick={(e)=>{this.makeClick(e, vehicleMake[i].id, vehicleMake[i].label)}}>
<a href={vehicleMake[i].href}>{vehicleMake[i].label}</a>
</li>
);
}
return listItems;
};
makeClick = (e, id, label) => {
console.log(id, label);
let state = this.state;
state.make = id;
this.setState(state);
console.log(state.make);
};
render() {
return (
<div>
{this.createMakeList()}
</div>
)
}
}
export default Make;
Model.js
import React, { Component } from 'react';
import '../CSS/App.css';
const vehicleModel = [
{id:1,label:"RZR 570",href:"#"},
{id:2,label:"RZR 900",href:"#"},
{id:3,label:"RZR S 900",href:"#"},
{id:4,label:"RZR S 1000",href:"#"},
{id:5,label:"RZR S 1000 TURBO",href:"#"}
];
class Model extends Component {
constructor(props){
super(props);
this.state = {
model: null
}
}
createModelList = () => {
let listItems = [];
for(let i = 0; i < vehicleModel.length; i++){
listItems.push(
<li className={`list ${this.state.model === vehicleModel[i].id ? "active" : ""}`} onClick={(e)=>{this.modelClick(e, vehicleModel[i].id, vehicleModel[i].label)}}>
<a href={vehicleModel[i].href}>{vehicleModel[i].label}</a>
</li>
);
}
return listItems;
};
modelClick = (e, id, label) => {
console.log(id, label);
let state = this.state;
state.model = id;
this.setState(state);
};
render() {
return (
<div>
{this.createModelList()}
</div>
)
}
}
export default Model;
这是主要的App.js
import React, { Component } from 'react';
import './CSS/App.css';
import { Container, Row, Col } from 'reactstrap';
import rzrPic from './Media/rzr-xp-1000-eps-trails-rocks-media-location-1-xxs.jpg';
import camsoT4S from './Media/camso-atv-t4s.jpg';
import Year from './Components/Year';
import Make from './Components/Make';
import Model from './Components/Model';
class App extends Component {
render() {
return (
<div className="App">
<Container fluid="true">
<Row>
<Col xs="3" className="categories">
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE YEAR
</h2>
</span>
<div className="categoryList">
<ul>
<Year/>
</ul>
</div>
</div>
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE MAKE
</h2>
</span>
<div className="categoryList">
<ul>
<Make/>
</ul>
</div>
</div>
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE MODEL
</h2>
</span>
<div className="categoryList">
<ul>
<Model/>
</ul>
</div>
</div>
</Col>
<Col xs="6" className="fill">
<img src={rzrPic} alt="rzr xp 1000"/>
</Col>
<Col xs="3" className="categories">
<span className="categoryHeader2">
<h2 className="categoryHeading">
AVAILABLE TRACKS
</h2>
</span>
<div className="Track">
<img src={camsoT4S} alt="Camso T4S Tracks"/>
<div className="TrackInfo">
<h3>CAMSO T4S - 4 SEASON</h3>
<p>Starting at $3,999.00</p>
<span>
ADD TO CART
</span>
</div>
</div>
<div className="Track">
<div className="TrackInfo">
<h3>CAMSO T4S - 4 SEASON</h3>
<p>Starting at $3,999.00</p>
<p className="select">SELECT</p>
</div>
</div>
</Col>
</Row>
</Container>
</div>
);
}
}
export default App;
在此先感谢您的帮助!
答案 0 :(得分:1)
与其在每个组件中存储选定的年份/品牌/型号,不如将它们存储在父级App
中。然后,您将在App
组件中处理重置逻辑。
以下是重构代码的方法:
import React, { Component } from "react";
import "../CSS/App.css";
// The list of years is now passed as props
//
// const vehicleYear = [];
class Year extends Component {
// You dont need the constructor anymore as the component
// doesn't have a state to initialize
//
// constructor(props) {}
createYearList = () => {
// Use the year list passed as a prop from the parent
const { vehicleYear } = this.props;
let listItems = [];
for (let i = 0; i < vehicleYear.length; i++) {
listItems.push(
<li
className={`list ${
this.state.year === vehicleYear[i].id ? "active" : ""
}`}
onClick={e => {
this.yearClick(e, vehicleYear[i].id, vehicleYear[i].label);
}}
>
<a href={vehicleYear[i].href}>{vehicleYear[i].label}</a>
</li>
);
}
return listItems;
};
yearClick = (e, id, label) => {
// Call the onClick function passed as a prop from the parent
this.props.onClick(e, id, label);
};
render() {
return <div>{this.createYearList()}</div>;
}
}
export default Year;
我只修改了Year
组件,因为Make
和Model
组件具有相同的结构。我待会儿再讲。
这是在Year
中使用App
的方法:
import React, { Component } from 'react';
// import ...
// Define the list of years
const vehicleYear = [
{id:1,label:"2019",href:"#"},
{id:2,label:"2018",href:"#"},
{id:3,label:"2017",href:"#"},
{id:4,label:"2016",href:"#"},
{id:5,label:"2015",href:"#"},
{id:6,label:"2014",href:"#"}
];
class App extends Component {
constructor(props){
super(props);
// Initialise the state of the App component
this.state = {
year: null,
}
}
// Move the click handler from the Year component to its parent component
yearClick = (e, id, label) => {
this.setState({
year: id
});
};
render() {
return (
<div className="App">
<Container fluid="true">
<Row>
<Col xs="3" className="categories">
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE YEAR
</h2>
</span>
<div className="categoryList">
<ul>
{/* Pass the list of years, the selected year and the handler to
select a year to the Year component */}
<Year vehicleYear={vehicleYear} selectedYear={this.state.year} onClick={this.yearClick} />
</ul>
</div>
</div>
...
</Row>
</Container>
</div>
);
}
}
export default App;
现在,您已完全控制了Year
,并由App
组件处理了逻辑。如果要重置选定的年份,只需在App
组件中创建并调用这样的函数:
resetYear = () => {
this.setState({
year: null
});
};
您可以将Year
,Make
和Model
组件重新引用为一个可重用组件,因为它们的结构完全相同。这是从中提取的ListComponent
:
// The list components takes three arguments:
// - itemsList: items to be displayed
// - selectedItemId: the id of the selected item
// - onSelect: a function to call when an item is selected
class ListComponent extends Component {
render() {
const { itemsList, selectedItemId, onSelect } = this.props;
return (
<div>
{itemsList.map(item => (
<li
className={`list ${selectedItemId === item.id ? "active" : ""}`}
onClick={e => {
onSelect(e, item.id, item.label);
}}
>
<a href={item.href}>{item.label}</a>
</li>
))}
</div>
);
}
}
export default ListComponent;
您可以像这样使用它:
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE YEAR
</h2>
</span>
<div className="categoryList">
<ul>
<ListComponent onSelect={this.selectYear} itemsList={vehicleYear} selectedItemId={this.state.year}/>
</ul>
</div>
</div>
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE MAKE
</h2>
</span>
<div className="categoryList">
<ul>
<ListComponent onSelect={this.selectMake} itemsList={vehicleMake} selectedItemId={this.state.make}/>
</ul>
</div>
</div>
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE MODEL
</h2>
</span>
<div className="categoryList">
<ul>
<ListComponent onSelect={this.selectModel} itemsList={vehicleModel} selectedItemId={this.state.model}/>
</ul>
</div>
</div>
答案 1 :(得分:0)
在这种情况下,最简单的解决方案是将您的状态保留在父级中,或者将组件临时创建为组件的父级,然后简单地传递一个onChangeYear属性,例如更改状态你的父母
import React, { Component } from 'react';
import './CSS/App.css';
import { Container, Row, Col } from 'reactstrap';
import rzrPic from './Media/rzr-xp-1000-eps-trails-rocks-media-location-1-xxs.jpg';
import camsoT4S from './Media/camso-atv-t4s.jpg';
import Year from './Components/Year';
import Make from './Components/Make';
import Model from './Components/Model';
class App extends Component {
contructor(props) {
super(props);
this.state = { year: "" }
}
render() {
return (
<div className="App">
<Container fluid="true">
<Row>
<Col xs="3" className="categories">
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE YEAR
</h2>
</span>
<div className="categoryList">
<ul>
<Year onChangeYear={(year) => {this.setState({year})/>
</ul>
</div>
</div>
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE MAKE
</h2>
</span>
<div className="categoryList">
<ul>
<Make/>
</ul>
</div>
</div>
<div>
<span className="categoryHeader">
<h2 className="categoryHeading">
VEHICLE MODEL
</h2>
</span>
<div className="categoryList">
<ul>
<Model/>
</ul>
</div>
</div>
</Col>
<Col xs="6" className="fill">
<img src={rzrPic} alt="rzr xp 1000"/>
</Col>
<Col xs="3" className="categories">
<span className="categoryHeader2">
<h2 className="categoryHeading">
AVAILABLE TRACKS
</h2>
</span>
<div className="Track">
<img src={camsoT4S} alt="Camso T4S Tracks"/>
<div className="TrackInfo">
<h3>CAMSO T4S - 4 SEASON</h3>
<p>Starting at $3,999.00</p>
<span>
ADD TO CART
</span>
</div>
</div>
<div className="Track">
<div className="TrackInfo">
<h3>CAMSO T4S - 4 SEASON</h3>
<p>Starting at $3,999.00</p>
<p className="select">SELECT</p>
</div>
</div>
</Col>
</Row>
</Container>
</div>
);
}
}
export default App;
如果您发现自己的Web应用程序中有很多组件,我会考虑集成Redux以全局处理状态https://redux.js.org/introduction/getting-started。