Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

child component is not rerendering. #72

Closed
viperfx opened this issue Mar 5, 2019 · 3 comments
Closed

child component is not rerendering. #72

viperfx opened this issue Mar 5, 2019 · 3 comments

Comments

@viperfx
Copy link

viperfx commented Mar 5, 2019

So I have

import createContainer from "constate";
export const Form = createContainer(useFormState, value => [value.values]);
function formReducer(state, action) {
  switch (action.type) {
    case 'add-text':
      let newState = {
        ...state,
        report_fields: [...state.report_fields, {value:null, type:'text'}]
      }
      return newState;
    default:
      throw new Error();
  }
}

function useFormState({ initialValues = {} } = {}) {
  const [state, dispatch] = useReducer(formReducer, initialValues);
  return { state, dispatch };
}
<Form.Provider initialValues={{report_fields: props.report_fields, report: props.report, team: props.team}}>
   <Wizard/>
</Form.Provider>

The Wizard does this

function Wizard() {
  const { step, next, previous } = useContext(Step.Context);
  const steps = [StepOneQuestions, StepTwoMembers];
  return React.createElement(steps[step]);
}

And in StepTwo

export default function StepOneQuestions (props) {
    const {state, dispatch} = useContext(Form.Context);
    
    return ( .... )
}

That StepOneQuestions is not re-rendering when dispatching an action such as add-text

@diegohaz
Copy link
Owner

diegohaz commented Mar 5, 2019

Hi @viperfx

export const Form = createContainer(useFormState, value => [value.values]);
                                                                  ^

useFormState doesn't return .values. You should probably use [value.report_fields, value.report, value.teams] or don't pass anything there.

Edit:

This is the correct usage for your case:
export const Form = createContainer(useFormState, ({ state }) => [...state.report_fields, state.report, state.team]);

Nevermind, you have deep objects and arrays. Computing changes on your state would be probably more expensive than re-rendering components.

@viperfx
Copy link
Author

viperfx commented Mar 5, 2019

hey @diegohaz thanks for the quick reply. I change to export const Form = createContainer(useFormState); and it worked as expected.

I realise now I was using your wizard example on the repo, but I change the hook return signature.

So leaving it blank - does that have any impact?

So if I called my state, values in my return for hooks such as { values, dispatch } that would have worked?

@diegohaz
Copy link
Owner

diegohaz commented Mar 5, 2019

If you leave it blank, consumers will re-render whenever the Provider re-renders (even when its state hasn't changed). For most apps it shouldn't be a problem though.

See https://github.com/diegohaz/constate#creatememoinputs

@diegohaz diegohaz closed this as completed Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants