0

Back again with another react question!

UserInfoStep.js (Child)

    function UserInfoStep({ PUID, FirstName, handleChangeParent }) {
    const { dispatch } = useContext(ContactFormContext);

    return (
        //some controls

        <FormControl>
            <Grid container spacing={3}>

                <Grid item xs={12}>
                    <TextField required label="PUID"
                        style={{ width: '100%' }}
                        name="PUID"
                        onChange={e =>
                            dispatch({ type: "PUID", payload: e.target.value })
                        }
                        value={PUID} variant="outlined" />
                </Grid>
            </Grid>

            <Grid item xs={12} md={6}>
                <TextField
                    required
                    style={{ width: '100%' }}
                    label="First Name"
                    name="FirstName"
                    onChange={e =>
                        dispatch({ type: "FIRST_NAME_CHANGE", payload: e.target.value })
                    }
                    value={FirstName}

                    variant="outlined"
                />
            </Grid>
        </FormControl>
    );
}

export default UserInfoStep;

ContactForm.js (Parent)

    const initialState = {
    PUID: "",
    FirstName: "",
    total: 0
    //other params removed
};

function formReducer(state, action) {
    switch (action.type) {
        case "PUID":
            fetch('https://api.npms.io/v2/search?q=react')
                .then(result => result.json())
                .then(data => {

                    console.log(data.total);
                });
            return { ...state, PUID: action.payload };
        case "FIRST_NAME_CHANGE":
            return { ...state, FirstName: action.payload };
        default:
            throw new Error();
    }
}

function ContactForm() {
    const { PUID, FirstName, total } = state;


    const steps = [
        <UserInfoStep handleChangeParent={handleChange} {...{ PUID, FirstName }} />,
    ];

    return (
        <ContactFormContext.Provider value={{ dispatch }}>
    //some code removed

        </ContactFormContext.Provider>
    );
}

export default ContactForm;

I want to set the value returned from the API call (data.total), in the FirstName input box when PUID onChange triggers. The API call can also be moved to the Child (UserInfoStep) if needed.

Edit

I have now moved my API call to UserInfoStep.js

const onPUIDChanged = (event) => {    
fetch('https://api.npms.io/v2/search?q=react')
  .then(result => result.json())
  .then(data => {        
    console.log(data.total);
  });
dispatch({ type: "PUID", payload: event.target.value });            
};


<Grid item xs={12}>
      <TextField required label="PUID"
      style={{width:'100%'}}
      name="PUID"
      onChange={onPUIDChanged}
      value={PUID} variant="outlined"/>
    </Grid>
1
  • Reducers are not async so you have to use thunk for redux or dispatch after fetch when you used useReducer (not clear what you are using). When you set async result on user input make sure you set the last async result. Commented Oct 27, 2021 at 6:33

1 Answer 1

1

Don't use API call in your reducer, the reducer is just a function that gets an action and returns the state.

The philosophy of using action - reducer - store in redux architecture is to separate the logic.

There are two options for you:

  1. using a third library like redux-saga to control the async API calling and handle the side effects with the power of generators.

  2. call the API in your component/page and then dispatch the proper action for success/failure cases.

Sign up to request clarification or add additional context in comments.

2 Comments

option 2 seems feasible as I am a beginner :)
Now if I add FirstName = "ABC"; in onpuidchanged..it should be displayed in the firstname textfield?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.