为了账号安全,请及时绑定邮箱和手机立即绑定

使用 concat 与直接赋值时 setState 有什么区别吗?

使用 concat 与直接赋值时 setState 有什么区别吗?

沧海一幻觉 2021-12-12 10:34:53
import React, { Component } from "react";import axios from "axios";import ReactPlayer from "react-player";export default class DoctorData extends Component {  state = {    sidebarOpen: true,    courseData: [],    renderData: []  };  componentDidMount() {    let jwtToken = { accessToken: "" };    axios.post(" ", jwtToken).then(data => {      console.log(data);      this.setState({        courseData: data.data.courseDetails.userModuleDetailsV2      });    });  }  RenderComponent = () => {    console.log("we are inside sideBarComponet");    return (      <div className="card">        {this.state.courseData.map((value, key) => {          console.log(value);          console.log("we are inside key", key);          //   console.log(value.userLessonDetails[key].userChapterDetails[0].chapter.content)          return (            <div>              <div className="card-header">                <h4>Doctor-content</h4>                <ReactPlayer                  url={                    value.userLessonDetails[0].userChapterDetails[0].chapter                      .content                  }                  playing                />                {console.log(                  "we are printing the content",                  value.userLessonDetails[0].userChapterDetails[0].chapter                    .content                )}                {console.log(typeof this.state.courseData)}              </div>            </div>          );        })}      </div>    );  };  render() {    return (      <div>        {this.state.courseData.length ? (          <div>{this.RenderComponent()}</div>        ) : null}        {console.log("fghjkl", this.state.courseData)}        {this.state.courseData.length}      </div>    );  }}
查看完整描述

2 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

.concat()

该concat()方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。


这证实在状态的不可变更新中使用是安全的。


请注意,对于作为参数传递的任何值,它的工作原理相同,但有点扁平化数组。


该concat方法创建一个新数组,该数组由调用它的对象中的元素组成,对于每个参数,按顺序依次是该参数的元素(如果该参数是一个数组)或该参数本身(如果该参数是不是数组)。它不会递归到嵌套数组参数中。


[1].concat(['test'])   //=> [1, "test"]

[1].concat('test')     //=> [1, "test"]

[1].concat([['test']]) //=> [1, ["test"]]

.concat创建一个包含旧this.state.courseData值和接收到的新值的新数组。由于初始状态是一个空数组[],除非data.data.courseDetails.userModuleDetailsV2不是数组,否则两者结果相同。


this.state.courseData.concat(data.data.courseDetails.userModuleDetailsV2)

相当于


[].concat(newValues)

// or just

newValues // if array

[newValues] // if something else

所以两者都是相同的,但.concat在这里是不必要的,因为它只会在内部调用一次,componentDidMount 除非 this.state.courseData预先填充了来自 props 或其他地方的默认数据。


删除时不起作用.concat?

这意味着它data.data.courseDetails.userModuleDetailsV2可能不是一个数组,并且您期望在 render 方法中有一个数组,但是当 axios 调用成功时(以及在 之后setState),它不再是数组了。


this.setState({

  courseData: this.state.courseData.concat(

    data.data.courseDetails.userModuleDetailsV2

  )

})

//=> [data.data.courseDetails.userModuleDetailsV2]


this.setState({

  courseData: data.data.courseDetails.userModuleDetailsV2

})

//=> data.data.courseDetails.userModuleDetailsV2

话虽.concat如此,如果您要添加“获取更多”功能,那么使用它可能会很有用。


onFetchMore = (offset) => {

  fetchMoreAxiosCall(offset)

    .then(newData => this.setState(({ courseData }) => ({ 

      courseData: courseData.concat(newData)

    })))

}

您可以只更新状态内所需的值,而无需传播旧状态 ( { ...state, courseData: /**/ }) 因为 ( source ):


更新器的输出与状态浅合并。


查看完整回答
反对 回复 2021-12-12
?
米脂

TA贡献1836条经验 获得超3个赞

相反,ReactpreviousState通过传递一个接受先前状态作为第一个参数的函数来提供,例如



// general

this.setState((oldState) => ({ ...oldState }));


// useful for updating objects

this.setState(({ myObject }) => ({ 

    myObject: { ...myObject, propToUpdate: true }

  })

);


查看完整回答
反对 回复 2021-12-12
  • 2 回答
  • 0 关注
  • 317 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信