JavaScript数组映射返回空数组

JavaScript数组映射返回空数组,javascript,reactjs,Javascript,Reactjs,我想有一个上传机制,上传图片并将其转换为base64字符串,然后将其保存到一个状态。之后,我想映射到一个组件中。但事实证明,Array.map()在这种情况下返回一个空数组。array.map是否有限制 类TestFileInput扩展了React.Component{ 建造师(道具){ 超级(道具); this.fileToBase64=this.fileToBase64.bind(this); 此.state={ 示例图片:未定义 } } fileToBase64(文件){ 让数组=[];

我想有一个上传机制,上传图片并将其转换为base64字符串,然后将其保存到一个状态。之后,我想映射到一个组件中。但事实证明,
Array.map()
在这种情况下返回一个空数组。array.map是否有限制

类TestFileInput扩展了React.Component{
建造师(道具){
超级(道具);
this.fileToBase64=this.fileToBase64.bind(this);
此.state={
示例图片:未定义
}
}
fileToBase64(文件){
让数组=[];
for(设i=0;i
{this.state.examplePictures!==未定义(
{this.state.examplePictures.map(pic=>(
))}
):""}
);
}
}
所以基本上,当你上传图片的时候。调用
fileToBase64
时,返回一个使用base64字符串的数组(该数组有效)。他们被保存到国家(这也行)。只有映射返回空数组


这是一个小提琴

我想你错过了
文件阅读器执行异步操作的事实。
将
examplePictures
添加到状态时,文件不会被转换

我设置了一个codesandbox(),我想它可以实现您想要的

我做了两件事:

首先,我建议使用
文件阅读器
,以便更轻松地操作它:

  readFileAsync = file => {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();

      reader.onload = event => {
        resolve(event.target.result);
      };
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  };

我更新
fileToBase64
函数以使用上一个函数,并在更新状态之前等待读取每个文件:

  async fileToBase64(files) {
    const examplePictures = await Promise.all(
      Array.from(files).map(this.readFileAsync)
    );
    this.setState({ examplePictures });
  }

Array.from(files)
只是用来将
文件列表
转换为
数组
,从而能够轻松地映射文件列表。

我认为您忽略了
文件阅读器
执行异步操作的事实。 将
examplePictures
添加到状态时,文件不会被转换

我设置了一个codesandbox(),我想它可以实现您想要的

我做了两件事:

首先,我建议使用
文件阅读器
,以便更轻松地操作它:

  readFileAsync = file => {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();

      reader.onload = event => {
        resolve(event.target.result);
      };
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  };

我更新
fileToBase64
函数以使用上一个函数,并在更新状态之前等待读取每个文件:

  async fileToBase64(files) {
    const examplePictures = await Promise.all(
      Array.from(files).map(this.readFileAsync)
    );
    this.setState({ examplePictures });
  }

Array.from(files)
只是用来将
文件列表
转换为
数组
,因此能够轻松地映射文件列表。

我认为
onLoad
是异步的,不知何故它没有正确地添加到状态。我对你的代码做了一些修改,它只在图像加载后添加到状态,并且只有在它有文件时才渲染

class TestFileInput extends React.Component {
  constructor(props){
        super(props);

    this.state = {
        examplePictures: []
    }
  }
   chooseFiles = (e) => {
     const files = e.target.files;
     let reader = new FileReader();
     reader.onload = (event) => {
       this.setState((previousState) => ({
         examplePictures: [
           ...previousState.examplePictures,
           event.target.result,
         ]
       }));
     };

     for(let i = 0; i < files.length; i++){
       let file = files[i];
       reader.readAsDataURL(file);
     }
   }
  render() {
    return (
        <div>
          <input type="file" multiple onChange={this.chooseFiles}/>
        {this.state.examplePictures.length > 0 && (
            <div>
            {this.state.examplePictures.map(pic => (
                <img src={pic} alt=""/>
            ))}
            </div>
        )}
      </div>
    );
  }
}

ReactDOM.render(
  <TestFileInput />,
  document.getElementById('container')
);

类TestFileInput扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
示例图片:[]
}
}
选择文件=(e)=>{
const files=e.target.files;
let reader=new FileReader();
reader.onload=(事件)=>{
this.setState((以前的状态)=>({
示例图片:[
…previousState.examplePictures,
event.target.result,
]
}));
};
for(设i=0;i0&&(
{this.state.examplePictures.map(pic=>(
))}
)}
);
}
}
ReactDOM.render(
,
document.getElementById('容器')
);

我认为
onLoad
是异步的,不知何故它没有正确地添加到状态中。我对你的代码做了一些修改,它只在图像加载后添加到状态,并且只有在它有文件时才渲染

class TestFileInput extends React.Component {
  constructor(props){
        super(props);

    this.state = {
        examplePictures: []
    }
  }
   chooseFiles = (e) => {
     const files = e.target.files;
     let reader = new FileReader();
     reader.onload = (event) => {
       this.setState((previousState) => ({
         examplePictures: [
           ...previousState.examplePictures,
           event.target.result,
         ]
       }));
     };

     for(let i = 0; i < files.length; i++){
       let file = files[i];
       reader.readAsDataURL(file);
     }
   }
  render() {
    return (
        <div>
          <input type="file" multiple onChange={this.chooseFiles}/>
        {this.state.examplePictures.length > 0 && (
            <div>
            {this.state.examplePictures.map(pic => (
                <img src={pic} alt=""/>
            ))}
            </div>
        )}
      </div>
    );
  }
}

ReactDOM.render(
  <TestFileInput />,
  document.getElementById('container')
);

类TestFileInput扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
示例图片:[]
}
}
选择文件=(e)=>{
const files=e.target.files;
let reader=new FileReader();
reader.onload=(事件)=>{
this.setState((以前的状态)=>({
示例图片:[
…previousState.examplePictures,
event.target.result,
]
}));
};
for(设i=0;i0&&(
{this.state.examplePictures.map(pic=>(
))}
)}
);
}
}
ReactDOM.render(
,
document.getElementById('容器')
);

数组
将是
[]
,因为您尚未链接onLoad事件<代码>推送
将在返回
数组
后发生,但状态具有所需的值,因此推送事件工作。我有
reader.onload
。尝试记录examplePictures,然后映射…
{console.log(this.state.examplePictures);this.state.examplePictures.map()}
<代码>推送工作,但只有在返回空数组后才能工作。是的,如果我记录它,examplepictures的值应该与base64字符串一起使用。但如果我映射它,它只返回空数组。具体在哪里?第一个用于回调,第二个用于