Griddle
Griddle copied to clipboard
rowData not supplied to cutomComponent in v1.2
Griddle version
1.2
Expected Behavior
CustomComponent receives rowData prop as in v0
Actual Behavior
customComponent only receives value and griddleKey
Steps to reproduce
const LinkToUser = props => {
console.log('props', props); // { value: 'Adam Smith', griddleKey: 2 }
const { value, rowData } = props;
const url = '/users/${rowData.id}';
return <Link to={url}>{value}</Link>;
};
...
<ColumnDefinition id="name" title="Name" order={1} customComponent={LinkToUser} />
I understand it is possible to over-ride the CellContainer component to pass additional props down but I couldn't see a rowData selector to use.
This seems like a pretty standard requirement to make it possible to link an ID in another column etc. Only alternative is to use the ID field as the link to user..
Any help appreciated, thanks
Did you figure out a way around this? I'm currently working around by closing over the containing data in render
, e.g.
const { data } = this.props;
const CustomColumn = ({ value, griddleKey }) => {
const objectId = _.get(data[griddleKey], '_id');
return <Link to={`/objects/${objectId}`}>{value}</Link>;
};
But this is causing bugs for me as I'm getting undefined errors if the data prop changes - presumably as it's not being passed in as a prop to CustomColumn
and so can be out of sync.
The Storybook includes an example of enhancing a custom component with rowData
: https://github.com/GriddleGriddle/Griddle/blob/90a46dbdcdeebca280f4b3d0f8a928f8ad7b9996/stories/index.js#L67-L71
const EnhanceWithRowData = connect((state, props) => ({
rowData: rowDataSelector(state, props)
}));
const LinkToUser = EnhanceWithRowData(props => {
console.log('props', props); // { value: 'Adam Smith', griddleKey: 2 }
const { value, rowData } = props;
const url = '/users/${rowData.id}';
return <Link to={url}>{value}</Link>;
});
@dahlbyk is correct. This is a deviation from how we were doing things in 0.x. We are currently taking an opt-in approach to this data for performance reasons. We are hoping to add a helper that is mostly that code provided as a util out of the box -- it seems like a use-case many people are bumping into.
We maybe could additionally make this something driven by a prop on CellDefinition too... something like <ColumnDefinition ..... includeRowData={true} />
. I would love any additional thoughts around this.
@ryanlanciaux - it certainly seems like a common use case. I guess about half of things I'd want to write a ColumnDefinition
for would do plain cell formatting (e.g. formatting a date or adding styling), while the other half would need rowData
(e.g. creating a fullName
from forename
and surname
, creating an href from an id).
@dahlbyk - thanks for the link. I'm not using redux in my project but should be able to translate.
Sorry, I was away and missed the responses until now.
I was looking into upgrading a project to 1.x but in the end we decided to leave things as they are so never got round to solving this.
I think the opt-in approach makes sense generally but it wasn't obvious how to go about this, even with the examples. Although I must have missed the example @dahlbyk pointed out, perhaps this would make a good standalone example for the docs rather than the more complicated ones provided?
@ryanlanciaux <ColumnDefinition ..... includeRowData={true} />
would certainly be easiest solution for us!
<ColumnDefinition ..... includeRowData={true} />
would certainly be easiest solution for us!
This seems reasonable, but down the road there may be additional data that only certain columns need. How about include={['rowData']}
with an extensibility point to specify how a given include
key should be selected?
That sounds like a good idea. My initial 2 second thought on this is that we'll make a bunch of enhancers for pulling things out of the store. The string passed into the array could refer to the key in the enhancer object. I'm thinking something like this..
{
rowData: enhanceWithRowData ...,
...
settings: enhanceWithSettings... // totally just made this one up
}
Then you could do something like <Griddle data={...} include={['rowData', 'settings']} />
and the code internally would say compose this stuff around this column (before it gets to customComponents).
:+1:
To clarify, do you mean include
on ColumnDefinition
rather than Griddle
? I suppose both could be supported.
Bonus points if there's a mechanism for plugins to inject additional enhancers.
It would be also great if can support passing down props to cell such as props from react-router "match.url"
It would be also great if can support passing down props to cell such as props from react-router "match.url"
ColumnDefinition
does have extraData
stubbed in, but it's not wired up yet. Would that be sufficient?
Yupe, I think that would do.
@ieow extraData
has been implemented in https://github.com/GriddleGriddle/Griddle/pull/675.
Sorry for late reply. I tried it, it works perfectly. Just may be the keyword 'cellProperties' is a bit long. :)
Just may be the keyword 'cellProperties' is a bit long. :)
To clarify: after we have a release in npm
with #675, values from extraData
will be available directly in props
. As you note, until then (and on older releases), you can pull extraData
out of cellProperties
.
Cool.That is great. Can't wait for that.
@ieow can you provide an example?
@yasserzubair , I don't get what you need. What example you mean?
I reqest an exmaple as well. Scenario is something like:
//testing customcpomponent
const ActionBar = () => {
return (
<div>
<span><i className="fa fa-external-link" /></span>
<span><i className="fa fa-arrow-right" /></span>
<span><i className="fa fa-address-book" /></span>
</div>
);
}
and usage in render is:
return(
<div>
<Griddle
data={result}
plugins={[plugins.LocalPlugin]}
>
<RowDefinition>
<ColumnDefinition id="id" />
<ColumnDefinition id="createdAt" />
<ColumnDefinition id="owner.name" title="Owner" />
<ColumnDefinition id="recipient.name" title="recipient" />
<ColumnDefinition id="total.amount" title="price"/>
<ColumnDefinition title="actions" >
<ActionBar />
</ColumnDefinition>
</RowDefinition>
</Griddle>
</div>
);
@janpauldahlke did you try something like this?
...
<ColumnDefinition title="actions" customComponent={ActionBar} />
...
@dahlbyk Hi :) so is there any way to get row data in customComponent of ColumnDefinition?
Oh I see
const EnhanceWithRowData = connect((state, props) => ({
rowData: selectors.rowDataSelector(state, props)
}));
A little bit heavy but fine, thx :)