Nivo: Same key error when using custom tickValues array with empty strings to skip labels

Created on 19 Apr 2019  路  4Comments  路  Source: plouc/nivo

I don't know if this is a big problem but I'd like to stop it from throwing console errors.

The suggested technique to skip values on an axis is to provide your own tickValues array where you intentionally use empty strings every other index (or every few indexes). This causes a React render warning that two children have the same key (empty string).

Seems Nivo is using the x axis label as a the unique key value. Most of the time it should be unique, except when you want to hide it and it's an empty string. But in some other cases, such as a date where you trim the time of day, two axes read the same date even though the underlying value is different. This causes duplicate keys.

_Originally posted by @stahlmanDesign in https://github.com/plouc/nivo/issues/147#issuecomment-468777660_

Most helpful comment

@plouc OK great, the solution is to use format instead of messing with the values that should be unique keys.

I'd like to have the index in the format method like this format: (v, i) => i%2 === 0 ? '' : v but the index is not there.

But it is possible before render to create an array of values you want to appear, and then format: v => valuesToShow.find(vts => vts === v) ? v : ''

This works and fixes the error and does not use a hack.

All 4 comments

Using the x value seems to be the right approach as it's also used to keep ticks identity while transitioning from one state to another when animate is true.

Using empty values is a hack, and the library hasn't been designed to support this, sorry.

The value is used as a key, not the label, if you want to format the value, you should use a formatter.

@plouc OK great, the solution is to use format instead of messing with the values that should be unique keys.

I'd like to have the index in the format method like this format: (v, i) => i%2 === 0 ? '' : v but the index is not there.

But it is possible before render to create an array of values you want to appear, and then format: v => valuesToShow.find(vts => vts === v) ? v : ''

This works and fixes the error and does not use a hack.

But it is possible before render to create an array of values you want to appear, and then format: v => valuesToShow.find(vts => vts === v) ? v : ''

Hey, I know you posted a while ago, but do you have a code example? I am trying to skip ticks. Thanks

But it is possible before render to create an array of values you want to appear, and then format: v => valuesToShow.find(vts => vts === v) ? v : ''

Hey, I know you posted a while ago, but do you have a code example? I am trying to skip ticks. Thanks

Hey, I can help.
The above solution is saying you need to map over your data to create a valuesToShow array of values.

const valuesToShow = data.map((v,i)=>i % 2 === 0 ? '' : v)

Once you have that, you can add a format property to your axisBottom prop.

<Bar axisBottom={{ format: v => valuesToShow.find(vts => vts === v) ? v : "" }} />

Which will give you the desired result.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Buvaneshkumar7 picture Buvaneshkumar7  路  3Comments

dubzzz picture dubzzz  路  3Comments

stahlmanDesign picture stahlmanDesign  路  3Comments

knackjax picture knackjax  路  3Comments

serendipity1004 picture serendipity1004  路  3Comments