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>
    );
  }
}


在上面的代码中,我只是从api中获取数据并使用setState存储数据,并通过它进行渲染


这些步骤很混乱

  componentDidMount() {
    let jwtToken = { accessToken: "" };
    axios.post(" ", jwtToken).then(data => {
      console.log(data);
      this.setState({
        courseData: this.state.courseData.concat(
          data.data.courseDetails.userModuleDetailsV2
        )
      });
    });
  }


我用concat在setState中分配数据
在那之前我用过

this.setState({
  courseData: data.data.courseDetails.userModuleDetailsV2
})

我教过两个都是一样的,但是在使用courseData: data.data.courseDetails.userModuleDetailsV2
我的页面没有播放视频,有什么区别吗?但是在以下情况下为什么要播放媒体。
我尝试console.log内容,在两种情况下,内容都是相同的(显示mp4文件)
首先,我从axios获取对象类型,因此我将所需的数据切片并存储在setState中。

最佳答案

.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在这里是不必要的,因为componentDidMountthis.state.courseData中仅被调用一次,除非.concat用props或其他地方的默认数据预先填充。



删除data.data.courseDetails.userModuleDetailsV2时不起作用?

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

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




话虽如此,如果您要添加“获取更多”功能,则使用{ ...state, courseData: /**/ }可能会很有用。

onFetchMore = (offset) => {
  fetchMoreAxiosCall(offset)
    .then(newData => this.setState(({ courseData }) => ({
      courseData: courseData.concat(newData)
    })))
}


由于(source),您可以仅更新状态内想要的值,而无需扩展旧状态():


  更新器的输出与state合并在一起。

关于javascript - 使用concat与直接分配值时setState有什么区别吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58649158/

10-12 00:10
查看更多