GriddleGriddle / Griddle

Simple Grid Component written in React
http://griddlegriddle.github.io/Griddle/
MIT License
2.5k stars 378 forks source link

React-Redux 6.0.0 Upgrade fails with : TypeError: state.get is not a function #841

Open Debananda opened 5 years ago

Debananda commented 5 years ago

Griddle version

1.13.1 react-redux : 6.0.0 react : 16.6.7

Expected Behavior

enhancedWithRowData shall work properly giving rowData

Actual Behavior

enhancedWithRowData giving error

Steps to reproduce

upgrade react-redux to 6.0.0. then griddle react fails as given below × ←→1 of 6 errors on the page TypeError: state.get is not a function rowDataSelector src/main/webapp/src/core/Table/enhancedWithRowData.js:4 1 | import { connect } from 'react-redux'; 2 | 3 | const rowDataSelector = (state, { griddleKey }) => {

4 | return state 5 | .get('data') 6 | .find(rowMap => rowMap.get('griddleKey') === griddleKey) 7 | .toJSON();

Debananda commented 5 years ago

Possible Reason : Passing store as a prop to a connected component is no longer supported. Instead, you may pass a custom context={MyContext} prop to both and . You may also pass {context : MyContext} as an option to connect.

Ref : https://github.com/reduxjs/react-redux/releases

StefanoSega commented 5 years ago

Similar problem, since I updated react-redux to v6 I get this error: Error: Could not find "store" in the context of "Connect(Component)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React cont with this code:

<ColumnDefinition
                id="buttons"
                title=" "
                customComponent={griddleColumnExtendComponent(this.getButtonsComponent())}
              />
import { connect } from 'react-redux';

const rowDataSelector = (state: any, { griddleKey }: { griddleKey: string }) => state.get('data')
  .find((rowMap: any) => rowMap.get('griddleKey') === griddleKey)
  .toJSON();

export const griddleColumnExtendComponent = connect((state, props: any) => ({
  rowData: rowDataSelector(state, props)
}));
duvillierA commented 5 years ago

any updates?

hashaaan commented 5 years ago

Is there any update?

hashaaan commented 5 years ago

const enhancedWithRowData = ({ griddleKey }, data, callback) => { const rowData = data.find((row, index) => index === griddleKey); return callback({ rowData }); };

Can't find any solution so I apply my own solution

followbl commented 5 years ago

@juniorZed what'd you end up going with as a solution?

Huaoe commented 5 years ago

Anyone has an answer on this one ?

tip

761 is a must read

jackgeek commented 5 years ago

Interestingly the ability to pass a store as a prop was re-instated in react-redux v7.01

StefanoSega commented 5 years ago

React-Redux v7 connect actually returns an object and not a function or component anymore, like it is specified in this issue: https://github.com/reduxjs/react-redux/issues/1300 So even with v7 straight passing the result of connect to prop customComponent will not work.

ddelpiano commented 4 years ago

I know for the most won't be a solution, but in my case I proceeded with the following.

We had a scenario where we were enhancing one component with the rowData and some props provided by the parent component that was instantiating Griddle itself, as per code extracted below.

<Griddle
          data={this.state.stateVariablesTableData}
          // other code not relevant, removed for this extract
        >
          <RowDefinition>
            <ColumnDefinition
              title="Name"
              id="name"
            />
            <ColumnDefinition
              title="Watch"
              id="toggled"
              customComponent={enhancedWithRowData(
                this.props.onCheck,
                this.props.onUncheck,
                this.props.disabled
              )(
                ChooseVarComponent
              )}
            />

and then

export const rowDataSelector = (state, { griddleKey }) => state
  .get("data")
  .find(rowMap => rowMap.get("griddleKey") === griddleKey)
  .toJSON();

export const enhancedWithRowData = (onCheck, onUncheck, disabled) => connect((state, props) => ({
  rowData: rowDataSelector(state, props),
  onCheck,
  onUncheck,
  disabled
}));

This is where we were before to move to new react-redux, react and other libraries that have been upgraded. At this stage the need I had was to have the rowData.name prop since this was used in the ChooseVarComponent to trigger an action in our redux store since this variable had to be listed or not.

What I ended up doing (not ideal, but still a solution for us) was to replicate the data required per cell, so the function that was building the data to be given to Griddle, as per below

convertToStateVariablesTableData () {
    let tableData = [];

    this.state.stateVariables.map(item => {
      tableData.push({
        name: item,
        toggled: this.state.watchedVariables.includes(item)
      });
    });

    this.setState({
      stateVariablesTableData: tableData
    });
  }

has been modified in the following (this is the NOT efficient part since we have redundant information, but still, for now it address the problem and the information size on our side is negligible)

convertToStateVariablesTableData () {
    let tableData = [];

    this.state.stateVariables.map(item => {
      tableData.push({
        name: item,
        toggled: {
          status: this.state.watchedVariables.includes(item),
          item: item
        }
      });
    });

    this.setState({ stateVariablesTableData: tableData });
  }

so that we can import the customComponent as below

<ColumnDefinition
              title="Watch"
              id="toggled"
              headerCssClassName="toggleHeaderClass"
              customComponent={(props) => {
                return (
                <ChooseVarComponent
                  onCheck={this.props.onCheck}
                  onUncheck={this.props.onUncheck}
                  disabled={this.props.disabled}
                  {...props}
                />)}}
hashaaan commented 4 years ago

@juniorZed what'd you end up going with as a solution?

that was a temporary solution for me at that time like a year ago @followbl