1

I learn react and I am trying to create a stepper to manage my form correct,I'm looking for the best fit way to pass input value from one step to another The full code is bellow

here the input value from step 1 :

   <MDBInput
   label="exerciseManager"
   name="exerciseManager"
   type="text"
   value={formik.values.exerciseManager}
   onChange={formik.handleChange}
   outline
   size="lg"
   />

I want to pass formik.values.exerciseManager to step 2 so i can use it there

step 1 and step 2 in different js file

how should I do that correct?

this is step 1 : step1

I want it will show here : step2

full step 1 code

//now check that the value get correct to the database
const Certifications = (props) => {
//state             //Setstate
const [fieldApproveOptions, setFieldApproveOptions] = useState([])

//useEffect Hooks 
useEffect(() => {

    axios.get('/api/certifications/fieldApproveOptions?userId=1234567&rank=Colonel&force=Moran')
        .then(response => {
            console.log(response.data)
            setFieldApproveOptions(response.data.fieldApproveOptions)
        }
        ).catch(err => console.log(err))
}, [])

const formik = useFormik({

    initialValues: {
        exerciseName: '',
        //exerciseBy: '',  autofill current user from session
        exerciseOOB: '',
        exercisePOD: '',
        exerciseType: '', // options should be pull from db
        exerciseLive: '',
        fieldApprove: '', // options should be pull from db
        fileApprove: '', // options should be pull from db
        artilleryApprove: '', // options should be pull from db
        exerciseManager: '',
        trainerOfficerApprove: '', // options should be pull from db
        cerRes: '',
        fieldApproveOptions: []

    },

    onSubmit: values => {
        axios.post('/api/certifications', values)
            .then(function (response) {
                console.log(response);
            })
            .catch(function (error) {
                console.log(error);
            });
    },
})

return (
    <Card>
        <CardContent>
            <div className="Pedding">
                <MDBContainer fluid  >

                    <MDBRow center  >
                        <MDBCol md="4"  >
                            <div className="MDBColor">
                                <form onSubmit={formik.handleSubmit} autoComplete="off">
                                    <p className="h1 text-center" style={{ paddingTop: "10px", fontWeight: "bold" }}>Certifications</p>
                                    <div className="Certifications">

                                        <MDBInput
                                            label="Exercise name"
                                            name="exerciseName"
                                            type="text"
                                            onChange={formik.handleChange}
                                            value={formik.values.exerciseName}
                                            outline
                                            size="lg"
                                        />


                                        <MDBInput
                                            label="Exercise type"
                                            name="exerciseType"
                                            list="types"
                                            onChange={formik.handleChange}
                                            value={formik.values.exerciseType}
                                            outline
                                            size="lg"

                                        />

                                        <datalist id="types" >
                                            <option data-value="1" value="Open Terrain">Open Terrain</option>
                                            <option value="Urban warfare" >Urban warfare</option>
                                            <option value="Armoured fighting vehicle" >Armoured fighting vehicle</option>
                                            <option value="unplanned" >unplanned</option>
                                            <option value="live military exercise" >live military exercise</option>
                                        </datalist>






                                        <MDBInput
                                            label="Order of battle"
                                            name="exerciseOOB"
                                            type="number"
                                            min="20"
                                            onChange={formik.handleChange}
                                            value={formik.values.exerciseOOB}
                                            outline
                                            size="lg"
                                        />



                                        {/*FieldApprove button */}
                                        <MDBInput
                                            label="fieldApprove"
                                            name="fieldApprove"
                                            list="fieldApproves"
                                            onChange={formik.handleChange}
                                            value={formik.values.fieldApprove}
                                            outline
                                            size="lg"
                                        />
                                        <datalist id="fieldApproves" defaultValue>

                                            {fieldApproveOptions.map((option, i) =>
                                                <option key={i++} value={option.id}>
                                                    {option.rank + " " + option.firstName + " " + option.lastName}
                                                </option>)}
                                        </datalist>




                                        <MDBInput
                                            label="fileApprove"
                                            name="fileApprove"
                                            type="text"
                                            value={formik.values.fileApprove}
                                            onChange={formik.handleChange}
                                            outline
                                            size="lg"
                                        />
                                        <MDBInput
                                            label="artilleryApprove"
                                            name="artilleryApprove"
                                            type="text"
                                            value={formik.values.artilleryApprove}
                                            onChange={formik.handleChange}
                                            outline
                                            size="lg"
                                        />
                                        <MDBInput
                                            label="exerciseManager"
                                            name="exerciseManager"
                                            type="text"
                                            value={formik.values.exerciseManager}
                                            onChange={formik.handleChange}
                                            outline
                                            size="lg"
                                          

                                            
                                           

                                        />
                                        

                                        <MDBInput
                                            label="trainerOfficerApprove"
                                            name="trainerOfficerApprove"
                                            type="text"
                                            value={formik.values.trainerOfficerApprove}
                                            onChange={formik.handleChange}
                                            outline
                                            size="lg"

                                        />

                                        <div style={{ fontSize: "large", fontWeight: "bold" }} className="custom-control custom-checkbox">

                                            <input type="checkbox"
                                                onChange={formik.handleChange}
                                                value={formik.values.exerciseLive}
                                                className="custom-control-input"
                                                name="exerciseLive"
                                                id="live"
                                                value="on"

                                            />
                                            <label className="custom-control-label" htmlFor="live"> live exercise</label>
                                        </div>





                                        {/*pod section*/}
                                        <span style={{ fontSize: "large", fontWeight: "bold", float: "left" }} >part of the day:</span>
                                        <div className="forms" style={{ fontWeight: "bold" }} onChange={formik.handleChange} value={formik.values.exercisePOD}  >
                                            {/*night button*/}
                                            <label htmlFor="rdo1">
                                                <input type="radio" id="rdo1" name="exercisePOD" value="night" />
                                                <span className="rdo"></span>
                                                <span>night</span>
                                            </label>
                                            {/*day button*/}
                                            <label htmlFor="rdo2">
                                                <input type="radio" id="rdo2" name="exercisePOD" value="day" />
                                                <span className="rdo"></span>
                                                <span>day</span>
                                            </label>

                                        </div>






                                        <div className="text-center">
                                            <MDBBtn type="submit" color="yellow">Send</MDBBtn>
                                        </div>
                                    </div >
                                </form >
                            </div>
                        </MDBCol>
                    </MDBRow>

                </MDBContainer >

            </div>
        </CardContent>
    </Card>
);



}

export default Certifications;

here Soform.js full code

        const SoForm = () => {



 return (

   <p >
{formik.values.exerciseManager}
  </p>
 )
     }
   export default SoForm;

Here formikStepper code

export default function Home() {
return (
<Card>
  <CardContent>
    <FormikStepper
      initialValues={{
   
      }}
      onSubmit={async (values) => {
        await sleep(3000);
        console.log('values', values);
      }}
    >
      <FormikStep label="Certifications">
        <Box paddingBottom={2}>
        <Certifications   ></Certifications>
        </Box>
      </FormikStep>
      <FormikStep 
        label="loginPageF"

      >
        <Box paddingBottom={2}>
        <SoForm ></SoForm>
         
  • you want to pass it to child component, parent, or sibling.. or completely un-related components ? if child -> use props, if parent -> use callback, if sibling -> mix both.. completely un-related ? -> use react-redux – Maifee Ul Asad Sep 06 '20 at 20:24
  • you can use the [useFormik hook](https://formik.org/docs/api/useFormik) to get values. since I don't know the details of your form, I am not sure if that would work. I believe session storage is often used in that case, since with redux a refresh would delete all the data – tachko Sep 06 '20 at 20:32
  • @MaifeeUlAsad Hi step 1 and step 2 in different js file – check everytime Sep 06 '20 at 20:51
  • @tachko Hi I add two picture so it will be more understandable in the picture i fill the filed I want to show at step 2 – check everytime Sep 06 '20 at 20:52
  • they are in different js file, as they should be.. but what are their relation in between ?? from the illustrations you have provided I can make an wild guess that, there is some `Parent` component, where `Certification`, `Login` lies... if you provide minimal code, I can implement it there.. – Maifee Ul Asad Sep 07 '20 at 07:35
  • @MaifeeUlAsad hi I did it can you help me now?... – check everytime Sep 13 '20 at 19:26

1 Answers1

0

It's really hard to read and understands your code. Try to provide minimal reproducible statements. I can understand you problem, but can't work with your code. So I have created my won example. Here, codesandbox.io : https://codesandbox.io/s/elegant-shtern-362ki?file=/src/App.js

Let me explain it for you.

index.js -> is entry point, that calls only one component App, as we have no route
App.js -> is the parent component, which has two child, Certification and Panel
Certification.js -> takes input
Panel -> renders data from certification

If I'm not wrong, that's what you want. Render data in a component to another component, which are siblings to one another.

App.js :

import React from "react";
import Certifications from "./Certifications";
import Panel from "./Panel";

class App extends React.Component {
  state = {
    value1: "",
    value2: ""
  };

  fromCert = (name, value) => {
    this.setState({ [name]: value });
  };

  render() {
    return (
      <div>
        {this.state.value1}
        {this.state.value2}
        <Certifications fromCert={this.fromCert} />
        <Panel value1={this.state.value1} value2={this.state.value2} />
      </div>
    );
  }
}
export default App;

Panel.js:

import React from "react";

class Panel extends React.Component {
  render() {
    return (
      <div>
        Here we will render data from App, below
        <div>{this.props.value1}</div>
        <div>{this.props.value2}</div>
        Panel ends
      </div>
    );
  }
}

export default Panel;

Certification.js:

import React from "react";

class Certifications extends React.Component {
  state = {
    input1: "",
    input2: ""
  };
  onChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
    this.props.fromCert(e.target.name, e.target.value);
  };
  render() {
    return (
      <div>
        <input name="value1" onChange={this.onChange} />
        <input name="value2" onChange={this.onChange} />
        <div>
          Inside certificate
          <div>{this.state.input1}</div>
          <div>{this.state.input2}</div>
          Certificate ends
        </div>
      </div>
    );
  }
}
export default Certifications;

First of all, Certifications have two states - value1, value2. So I have given two input's name value1, value2. So that I can set value dynamically. Why? - just imagine I have 10 or 20 states. And that you have in your code.

And onChange of value, I'm triggering a callback to App with fromCert. Try passing 1000+ parameter, it will. :wink:

When I'm triggering that callback from certification, it's getting called in App.js's fromCert. Why is that? Cause I have passed that function or method as parameter - <Certifications fromCert={this.fromCert} />. So that's the reason why this function or method acts as callback. When I get those values, I just set them to App.js's state. Then pass them as props to Panel.

So whatever changes gets applied to Certification that comes to App, which then gets passed to Panel.

Certification -> App : Child to Parent communication
App -> Panel : Parent to Child communication
Certification -> Panel : Child to Child communication / Sibling communication

Try to imagine the hierarchy.

Thanks a lot. If you have any question, feel free to ask.

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
  • Hi first I want to Tank you !! on that solution. but this is not solve my case, yes you understand correct the hierarchy but the solve is for regular rcf and I use at rff and not regular rff I use formik hooks – check everytime Sep 15 '20 at 10:08
  • @checkeverytime facebook recommends to use rff, but I don't know why I love rcf... but the logic and underlying architectures are the same, right ?? if this helps you upvote.. cause formik hooks just return state of that component/functional-component.. so I think the use case is covered here.. thanks.. – Maifee Ul Asad Sep 17 '20 at 05:31
  • I make simple example here to explain my problem better https://stackoverflow.com/questions/63925561/formik-stepper-propshooks-between-steps – check everytime Sep 17 '20 at 08:35