在反应组件之间发送数据

问题描述 投票:0回答:1

对不起,我写了这么长的代码,但有人能帮我解决下面的问题吗?我试图将另一个对象的一些数据带入我的突变中,但当表单提交时,数据并没有随之而来,尽管表单中显示了正确的值。如果你看看下面的代码,你可以看到我已经包装了一个用户查询的突变,并使用me.address等来显示数据。

import styled from 'styled-components'
import React, { Component } from 'react';
import { Mutation } from 'react-apollo';
import User from './User';
import gql from 'graphql-tag';
import Router from 'next/router';
import Form from './styles/Form';
import Ghost from './styles/Ghost';
import Error from './ErrorMessage';

const Div = styled.div `
display: flex;
justify-content: center;
`;

const Container = styled.div `
    max-width: 1000px;
`;

const SINGLE_USER_QUERY = gql`
  query SINGLE_USER_QUERY($id: ID!) {
    user(where: { id: $id }) {
      id
      address
      lat
      lng
    }
  }
`;

const CREATE_JOB_MUTATION = gql`
  mutation CREATE_JOB_MUTATION(
    $name: String
    $address: String
    $email: String
    $description: String!
    $image: String!
    $cube: Int!
    $reqPickup: String
    $instructions: String!
    $feedback: String
    $lat: String
    $lng: String
    $pickup: DateTime
    $charges: Int
    $price: Int
  ) {
    createJob(
    name: $name
    address: $address
    email: $email
    description: $description
    image: $image
    cube: $cube
    reqPickup: $reqPickup
    instructions: $instructions
    feedback: $feedback
    lat: $lat
    lng: $lng
    pickup: $pickup
    charges: $charges
    price: $price
    ) {
      id
    }
  }
`;


class CreateJob extends Component {
    state = {
      name: '',
      address: '',
      email: '',
      description: '',
      image: '',
      cube: '',
      reqPickup: '',
      instructions: '',
      feedback: '',
      lat: '',
      lng: '',
      pickup: '',
      charges: '0',
      price: '0',
    };


    handleChange = (e) => {
      const { name, type, value } = e.target;
      const val = type === 'number' ? parseFloat(value) : value;
      this.setState({ [name]: val});
    };    

    componentDidMount() {
      console.log(this.state);
    };

    uploadFile = async e => {
      const files = e.target.files;
      const data = new FormData();
      data.append('file', files[0]);
      data.append('upload_preset', 'sickfits');

      const res = await fetch('https://api.cloudinary.com/v1_1/wesbostutorial/image/upload', {
        method: 'POST',
        body: data,
      });
      const file = await res.json();
      this.setState({
        image: file.secure_url,
        largeImage: file.eager[0].secure_url,
      });
    };

    render() {
        return (


          <Div>
          <Container>
          <User>
      {({ data }) => {
        const me = data ? data.me : null
        return (
          <Mutation mutation={CREATE_JOB_MUTATION} variables={this.state}>
            {(createJob, { loading, error }) => (
          <Form
          data-test="form"
          onSubmit={async e => {
            // Stop the form from submitting
            e.preventDefault();
            // call the mutation
            console.log(this.state);
            this.setState({ address: me.address });
            const res = await createJob();
            // change them to the single job page
            console.log(res);
            Router.push({
              pathname: '/job',
              query: { id: res.data.createJob.id },
            });
          }}>
                <Error error={error} />
            <fieldset disabled={loading} aria-busy={loading}>

                <label htmlFor="description"> 
                    Describe your waste: Just a few words to describe the materials.
                    <input
                    type="text"
                    id="description"
                    name="description"
                    placeholder="eg: wood, bricks, old kitchen tops and a fridge"
                    required
                    value={this.state.description}
                    onChange={this.handleChange}
                  />
                    </label>

                    <label htmlFor="instructions"> 
                    Instructions: Any specific instructions such as desired collection time or access info.
                    <input
                    type="text"
                    id="instructions"
                    name="instructions"
                    placeholder="Instructions for the collection team"
                    required
                    value={this.state.instructions}
                    onChange={this.handleChange}
                  />
                    </label>


                    <label htmlFor="address"> 
                    Address:
                    <input
                    type="text"
                    id="address"
                    name="address"
                    required
                    defaultValue={me.address}
                    onChange={this.handleChange}
                  />
                    </label>


                    <p
                    style={{
                        textAlign: 'center',
                      }}
                    >Click the submit button and we'll come back to you in just a few moments with a quote and collection time options</p>
                    <div
                     style={{
                        display: 'flex',
                        margin: 'auto',
                        justifyContent: 'center',
                      }}
                    >
                    <button
                    type="submit">SUBMIT</button>
                    </div>
                </fieldset>
            </Form>
            )}
            </Mutation>
            )
          }}
        </User>
            </Container>
          </Div>
        );
    }
}

export default CreateJob;
export { CREATE_JOB_MUTATION };
javascript reactjs graphql next.js react-apollo
1个回答
1
投票

假设 <User/> 包含查询组件和rendes子代... ... data 将包含你想存储在状态中的结果(当数据到达时)......

  {({ data }) => {
    // is data from query ready?
    const me = data ? data.me : null;
    // prevent looping (setState > rerendering)
    if( me && (me.address!=this.state.address) ) {
      setState( {address: me.address} )
    }
    return (
      <Mutation mutation={CREATE_JOB_MUTATION} 
        variables={this.state}
        onCompleted={(data)=>{
          console.log("mutated, result: ", data);
          // Router.push
        }}
      >
        {(createJob, { loading, error }) => (

你应该把这个功能(form+mutation)放在单独的组件中,用于管理内部的状态。 递给 更重要的是,不要把所有这些结构组件重新渲染。 组件在react中很便宜。)

就像Józef所说的那样,在调用时 "组成 "突变输入会更容易。

 createJob({variables: { ...this.state, address: me.address} })

await-ing没有意义,因为你应该用 onCompleted 回调。


-1
投票
const res = await createJob();

你是不是应该把param添加到 createJob 函数?

在这种情况下,它将是 await createJob({variables: this.state});

文档中的例子说明了这一点

© www.soinside.com 2019 - 2024. All rights reserved.