web-dev-qa-db-ja.com

ReactJS:Formikで画像/ファイルのアップロードを処理する方法?

ReactJSを使用して自分のサイトのプロファイルページをデザインしています。今私の質問は、ローカルマシンから画像をアップロードしてデータベースに保存し、プロファイルページに表示する方法です

_import React, {Component} from 'react';
import { connect } from 'react-redux';
import { AccountAction } from '../../actions/user/AccountPg1Action';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';

class AccountInfo extends Component {
  constructor(props) {
    super(props) 
    this.state = {
      currentStep: 1,
      userAccountData: {
        userid: '',
        useravtar: '',
        attachement_id: '',
   }
  }
 }

handleFileUpload = (event) => {
  this.setState({useravtar: event.currentTarget.files[0]})
};

handleChange = event => {
    const {name, value} = event.target
    this.setState({
      [name]: value
    })    
  }

handleSubmit = event => {
    let that = this;
    const { AccountAction } = that.props;
    event.preventDefault();

    let accountInputs = {
      userid: 49,
      useravtar: that.state.image,
      attachement_id: 478,
}
    that.setState({
      userAccountData: accountInputs,
    })

    AccountAction(accountInputs)
  }
AccountInfoView = () => {
console.log(this.state.useravtar)
    return (
      <section id="account_sec" className="second_form">
      <div className="container">
      <React.Fragment>
        <Formik
          initialValues={‌{
            file: null,
            email: '',
            phone: ''
          }}
          validationSchema={accountInfoSchema}
          render={(values) => {
          return(
        <Form onSubmit={this.handleSubmit}>
        <Step1 
          currentStep={this.state.currentStep} 
          handleChange={this.handleChange}
          file= {this.state.useravtar}
          handleFileUpload={this.handleFileUpload}
          />
          </Form>
        );
      }}
      />
      </React.Fragment>
      )
  }

  render() {    

    return (
      <div>{this.authView()}</div>
    )
  }
}

function Step1(props) {
console.log(props.useravtar)
  if (props.currentStep !== 1) {
    return null
  } 

  return(
    <div className="upload">
        <label htmlFor="profile">
          <div className="imgbox">
            <img src="images/trans_116X116.png" alt="" />
            <img src={props.useravtar} className="absoImg" alt="" />
          </div>
        </label>
<input id="file" name="file" type="file" accept="image/*" onChange={props.handleFileUpload}/>
        <span className="guide_leb">Add your avatar</span>
      </div>
  )
}
_

Event.target.file [0]のhandleChangeアクションでコンソールを実行すると、未定義で応答します。

また、handleSubmitアクションでconsole.log(this.state.useravtar)を実行すると、_c:/fakepath/imgname.jpg_のようなパス名が表示されます

PS:私は複数のフォームを持っているので、Stepで使用しています。そして、私はデータの保存にRedux Reducerを使用しています。

私は this リンクを参照しましたが、私の要件はこのように見えません。

9
aananddham

Formikはデフォルトではfileuploadをサポートしていませんが、以下を試すことができます

<input id="file" name="file" type="file" onChange={(event) => {
  setFieldValue("file", event.currentTarget.files[0]);
}} />

ここに "file"は、ファイルを保持するために使用しているキーを表します

送信時に、次を使用してファイルのファイル名、サイズなどを取得できます

onSubmit={(values) => {
        console.log({ 
              fileName: values.file.name, 
              type: values.file.type,
              size: `${values.file.size} bytes`
            })

ファイルをコンポーネントの状態に設定する場合は、次を使用できます

onChange={(event) => {
  this.setState({"file": event.currentTarget.files[0]})};
}}

あなたのコードによると、あなたは以下のようにファイルのアップロードを処理する必要があります

AccountInfoに、ファイルのアップロードを処理する関数を追加します

handleFileUpload = (event) => {
this.setState({WAHTEVETKEYYOUNEED: event.currentTarget.files[0]})};
}

以下のように同じ関数をStep1コンポーネントに渡します

    <Step1 
      currentStep={this.state.currentStep} 
      handleChange={this.handleChange}
      file= {this.state.image}
      handleFileUpload={this.handleFileUpload}
      />

ステップ1ファイルをアップロードするコンポーネントで、入力を次のように変更します。

<input id="file" name="file" type="file" accept="image/*" onChange={props.handleFileUpload}/>

アップロードした画像をプレビューする必要がある場合は、ブロブを作成して、以下のように画像のソースと同じものを渡すことができます

<img src={URL.createObjectURL(FILE_OBJECT)} /> 
7