0
votes

I have a react table with an edit button in each row. When the user clicks the button, it sends the id of it to my component. In that component, I am fetching data from an endpoint in my index.js. Then I call a reducer to update the state of tmpCriteria so that when a user clicks the edit button, it populates the /questionnaire page using tmpCriteria automatically. However, I'm not sure how to approach this now. Have I done it correctly so far? If so, how do I read the get request response data in my reducer and store it in tmpCriteria?

My index.js file:

export const EditButton = ({id}) => {
  const dispatch = useDispatch();
  
  const edit_criteria = async () => {
    try {
      let res = await axios.get(`http://localhost:3001/${encodeURIComponent(id)}`);
      dispatch(setTmpCriteria(res.data)); // update state with new data
      
    } catch (err) {
      console.error("DeleteButton", err.toJSON());
    }
  }

  return (
    <Link to="/questionnaire">
      <button className="edit-btn" title="Edit this criteria" onClick={()=>edit_criteria()}>
          <span role="img" aria-label="Edit this criteria">
            <Icon icon="bx:edit" inline={true} width={15} height={15} />
          </span>
      </button>
    </Link>
  )
}

res.data would look like this assuming the id parameter is 10:

[{"criteriaid":10,"criteriatypeid":2,"criteria":"Dummy text","rationale":"Dummy text","alttext":"--","testdescription":"Dummy text"}]

This is my questionnaire.js:

const initialState {
  criteriaFields: [
    { name: "Criteria", type: "input" },
    { name: "Rationale", type: "input" },
    { name: "Visual Example", type: "image" },
    { name: "Visual Example Rationale", type: "input" },
    {
      name: "Test Type",
      type: "dropdown",
      fields: ["type1", "type2", "type3"],
    },
    { name: "Description", type: "input" },
    { name: "Guidance Intro", type: "input" },
  ],
  answerFields: ["Points", "Label", "Guidance"],
  tmpCriteria: {
    criteriaId: "",
    criteria: "",
    rationale: "",
    visual: null,
    visualRational: "",
    testType: "",
    description: "",
    guidanceIntro: "",
    answers: [
      {
        point: 5,
        label: "",
        guidance: null,
      },
      {
        point: 4,
        label: "",
        guidance: "",
      },
      {
        point: 2,
        label: "",
        guidance: "",
      },
      {
        point: 0,
        label: "",
        guidance: "",
      },
      {
        point: null,
        label: "",
        guidance: null,
      },
    ],
  },
}

const QuestionnaireSlice = createSlice({
  name: "QUESTIONNAIRE",
    initialState,
    reducers: {
      setCriteriaField: (state, action) => {
        const { fieldName, value } = action.payload
        let tmp = { ...state.tmpCriteria }

        if (fieldName === "Rationale") {
          tmp = { ...tmp, rationale: value }
        } else if (fieldName === "Criteria") {
          tmp = { ...tmp, criteria: value }
        } else if (fieldName === "Visual Example") {
          tmp = { ...tmp, visual: value }
        } else if (fieldName === "Visual Example Rationale") {
          tmp = { ...tmp, visualRational: value }
        } else if (fieldName === "Test Type") {
          tmp = { ...tmp, testType: value }
        } else if (fieldName === "Description") {
          tmp = { ...tmp, description: value }
        } else if (fieldName === "Guidance Intro") {
          tmp = { ...tmp, guidanceIntro: value }
        }

        return {
          ...state,
          tmpCriteria: { ...tmp },
        }
      },
      setAnswerLabel: (state, action) => {
        const { value, idx } = action.payload

        const ans = state.tmpCriteria.answers.map((ans, i) =>
    i === idx ? { ...ans, label: value } : { ...ans }
        )

        return {
          ...state,
          tmpCriteria: {
            ...state.tmpCriteria,
            answers: ans,
          },
        }
      },
      setAnswerGuidance: (state, action) => {
        const { value, idx } = action.payload

        const ans = state.tmpCriteria.answers.map((ans, i) =>
    i === idx ? { ...ans, guidance: value } : { ...ans }
        )

        return {
          ...state,
          tmpCriteria: {
            ...state.tmpCriteria,
            answers: ans,
          },
        }
      },
      setTmpCriteria: (state, action) => ({ ...state, tmpCriteria: action.payload}),
    },
})

export const {
  setCriteriaField,
  setAnswerLabel,
  setAnswerGuidance,
  setTmpCriteria,
} = QuestionnaireSlice.actions

export default QuestionnaireSlice.reducer

I would appreciate any help with this, as I'm very new with React!

so i reducer specifically in setCriteriaField when you are restructuring this : const { fieldName, value } = action.payload. i am not seeing you passing you any fieldName to setCriteriaField. - Talha Fayyaz
That's where tmpCriteria is being set. So I believe I need my setTmpCriteria reducer to send in the data to tmpCriteria - viktor
So you have Link and then there is button that is calling the API. But what happens is that it redirects you to the '/questionnaire' without calling the API. - Talha Fayyaz
can you confirm this? - Talha Fayyaz