Javascript 对此做出反应。道具不要';t更新
有人能帮我理解为什么我过滤后这个.props不更新吗 这里是我的代码的精简版本Javascript 对此做出反应。道具不要';t更新,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,有人能帮我理解为什么我过滤后这个.props不更新吗 这里是我的代码的精简版本 export default class AutoList extends React.Component { constructor(props) { super(props); this.state = { filterValue: 'all', isHidden: true, autoOptValue: '' } } handleOnC
export default class AutoList extends React.Component {
constructor(props) {
super(props);
this.state = {
filterValue: 'all',
isHidden: true,
autoOptValue: ''
}
}
handleOnChangeBrand(evt) {
let selectedValue = evt.target.value;
this.setState({optionValue: selectedValue});
let filtered = this.props.autos.filter((auto) => {
if(auto.brands){
return auto.brands[0] === selectedValue;
}
return false;
});
console.log(this.props.auto) // still same number
console.log(filtered) // less autos. Actual filtered array
}
render() {
let autoDetail = this.props.autos.map(auto => {
return (
<Auto
key={auto.id}
id={auto.id}
name={auto.name}
brands={auto.brands ? auto.brands : false}/>
);
});
return (
<div>
<section>
<select id='autoFilter' className={this.state.isHidden ? 'u-is-hidden' : ''} onChange={this.handleOnChangeBrand.bind(this)} value={this.state.autoOptValue}>
<option value='brand1'> brand1 </option>
<option value='brand2'> brand2 </option>
</select>
</section>
<ul>
{autoDetail}
</ul>
</div>
);
}
导出默认类AutoList扩展React.Component{
建造师(道具){
超级(道具);
此.state={
filterValue:'所有',
伊希登:没错,
自动选项值:“”
}
}
Handleon品牌(evt){
让selectedValue=evt.target.value;
this.setState({optionValue:selectedValue});
let filtered=this.props.autos.filter((自动)=>{
if(汽车品牌){
返回自动。品牌[0]==所选值;
}
返回false;
});
console.log(this.props.auto)//仍然是相同的数字
console.log(过滤)//更少的autos.real过滤数组
}
render(){
让autoDetail=this.props.autos.map(auto=>{
返回(
);
});
返回(
品牌1
品牌2
{autoDetail}
);
}
基本上我有这个。prop.auto是一个100辆汽车的数组,每个都是一个有品牌的对象(这是另一个数组),每个都有2,3个品牌
我能够过滤,因为过滤后的会返回一个包含过滤后的汽车的数组,这些汽车是正确的。
但在此之后,this.props.auto不会更新,UI也不会更新
我做了一些类似的事情,但按品牌对汽车进行了分类,结果很顺利。
我不明白这里有什么不同
过滤器返回一个新的数组。这是因为你手头上仍然有原始数组。这是一件好事的原因有很多,实际上没有什么原因是坏事
道具是不可变的(就像你调用过滤器的数组一样)。不要更改Props
上的成员。也不要更改Props
的成员的成员,或者通常更改Props
的任何子代数据。
这就是state
存在的原因,因此,如果您必须这样做,您可以将其保存在那里
关于#2,通常情况下,您应该将这些内容提取到越来越高的抽象层中,完全脱离视图数据,只传递准备好显示的完成数据。this.props
在组件中实际上是不可变的,因此您无法更新this.props.autos的值
Array#filter
也是一个纯函数,因此被过滤的数组不会改变,而是返回一个新的过滤数组。这就是为什么在函数中记录filtered
时会看到过滤数组,但This.props.autos
没有改变
这个问题的简单答案是在渲染方法中进行过滤-我为false的optionValue
添加了初始状态,并在filter方法中对此进行了检查,如果仍然为false,则不进行过滤
export default class AutoList extends React.Component {
constructor(props) {
super(props);
this.state = {
filterValue: 'all',
isHidden: true,
autoOptValue: '',
optionValue: false
}
}
handleOnChangeBrand(evt) {
let selectedValue = evt.target.value;
this.setState({optionValue: selectedValue});
}
render() {
const { optionValue } = this.state;
const autoDetail = this.props.autos
.filter((auto) => {
if (!optionValue) return true;
if(auto.brands){
return auto.brands[0] === optionValue;
}
return false;
})
.map(auto => {
return (
<Auto
key={auto.id}
id={auto.id}
name={auto.name}
brands={auto.brands ? auto.brands : false}/>
);
});
return (
<div>
<section>
<select id='autoFilter' className={this.state.isHidden ? 'u-is-hidden' : ''} onChange={this.handleOnChangeBrand.bind(this)} value={this.state.autoOptValue}>
<option value='brand1'> brand1 </option>
<option value='brand2'> brand2 </option>
</select>
</section>
<ul>
{autoDetail}
</ul>
</div>
);
}
导出默认类AutoList扩展React.Component{
建造师(道具){
超级(道具);
此.state={
filterValue:'所有',
伊希登:没错,
自动选项值:“”,
选项值:false
}
}
Handleon品牌(evt){
让selectedValue=evt.target.value;
this.setState({optionValue:selectedValue});
}
render(){
const{optionValue}=this.state;
const autoDetail=this.props.autos
.filter((自动)=>{
如果(!optionValue)返回true;
if(汽车品牌){
返回自动品牌[0]==选项值;
}
返回false;
})
.map(自动=>{
返回(
);
});
返回(
品牌1
品牌2
{autoDetail}
);
}
该方法始终返回一个新的筛选数组,而不更改旧数组:
filter()方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素
在handleOnChangeBrand
事件中,您正在创建一个过滤数组,而不影响旧数组,但在React调用第二次渲染时不使用该过滤数组
下面是一个小示例,说明如何处理此问题:
1) 让react呈现您的默认autos
prop
export default class AutoList extends React.Component {
render() {
const autoDetail = this.props.autos.map(auto => {
return (
<Autos ... />
)
});
return (
<ul>
{ autoDetail }
</ul>
);
}
}
导出默认类AutoList扩展React.Component{
render(){
const autoDetail=this.props.autos.map(auto=>{
返回(
)
});
返回(
{autoDetail}
);
}
}
2) 添加一个单击处理程序和一个状态值,以保存要通过其进行筛选的值:
export default class AutoList extends React.Component {
constructor(props) {
super(props);
this.state = {
filter: '' // this is where we will store what we want to filter by
}
};
// All this function will do is update the state which we want to filter by
// this 'arrow function' auto bind 'this' for us, so we don't have to explicitely set .bind as you were doing before
handleOnChangeBrand = (event) => {
this.setState({
filter: event.target.value
})
};
render() {
const autoDetail = this.props.autos.map(auto => {
return (
<Autos ... />
)
});
return (
<ul>
{ autoDetail }
</ul>
);
}
}
导出默认类AutoList扩展React.Component{
建造师(道具){
超级(道具);
此.state={
筛选器:“”//这是存储要根据其进行筛选的内容的位置
}
};
//这个函数所要做的就是更新我们想要过滤的状态
//这个“箭头函数”为我们自动绑定“this”,所以我们不必像以前那样显式地设置.bind
handleOnChangeBrand=(事件)=>{
这是我的国家({
筛选器:event.target.value
})
};
render(){
const autoDetail=this.props.autos.map(auto=>{
返回(
)
});
返回(
{autoDetail}
);
}
}
3) 最后,我们将使用存储在状态中的值筛选出我们想要的汽车品牌,并使用它来构建我们的阵列
export default class AutoList extends React.Component {
constructor(props) {
super(props);
this.state = {
filter: '' // this is where we will store what we want to filter by
}
};
getFilteredAutos = () => {
// if we have no filter, return everything!
if (this.state.filter === '') {
return this.props.autos;
}
// this is returning the newely filtered array, without affecting the old one
return this.props.autos.filter(auto => {
if(auto.brands){
// we're filtering by our saved value
return auto.brands[0] === this.state.filter;
}
return false;
});
},
handleOnChangeBrand = (event) => {
this.setState({
filter: event.target.value
})
};
render() {
// we're mapping by the filtered results here
const autoDetail = this.getFilteredAutos().map(auto => {
return (
<Autos ... />
)
});
return (
<ul>
{ autoDetail }
</ul>
);
}
}
导出默认类AutoList扩展React.Component{
建造师(道具){
超级(道具);
此.state={
筛选器:“”//这是存储要根据其进行筛选的内容的位置
}
};
getFilteredAutos=()=>{
//如果我们没有过滤器,返回所有内容!
if(this.state.filter===''){
返回此.props.autos;
}
//这将返回新过滤的数组,而不影响旧数组
返回t