Filtering with map in reactjs - reactjs

I'm trying to do a filter in my app, where the content of the table to filter is defined in the reducer and comes as a state to the component. To do this i'm adding a filter to the mapping of the array.
{tilesData
.map((tile, i) => (
<GridListTile key={i}>
<img src={projectA} style={style.img} alt={tile.title} />
<GridListTileBar
title={<span>{tile.title}</span>}
subtitle={<span>{tile.address}, {tile.state} </span>}
actionIcon={
<Link to = 'project'>
<IconButton onClick={goToProject(i)} color='contrast'>
<VisibilityIcon />
</IconButton>
</Link>
}
/>
</GridListTile>
))
.filter(tilesData.title === project)
}
After doing this, it throws the following error:
TypeError: false is not a function

Related

React error: "Each child in a list should have a unique "key" prop."

Hi I am getting an error that says "each child in a list should have a unique "key" prop. When I check the Components using React Developer Tools I don't see any duplicates - what am I doing wrong?
return (
<>
<Modal
isOpen={modalIsOpen}
onRequestClose={closeModal}
>
{ modalIsOpen ? (
<Note
key={'ModalNote' + modalNote.id}
id={modalNote.id}
title={modalNote.title}
text={modalNote.text}
date={modalNote.date}
deleteNote={deleteNote}
closeNote={closeModal}
/>
) : ('')
}
</Modal>
<div className="notesForm">
<AddNote addNoteHandler={addNoteHandler}/>
</div>
<div className="notes">
{notes.map((note) => (
<>
<Note
key={note.id}
id={note.id}
title={note.title}
text={note.text}
date={note.date}
deleteNote={deleteNote}
closeNote={closeModal}
openModal={openModal}
modalIsOpen={modalIsOpen}
/>
</>
))}
</div>
</>
);
Try this, Instead of Fragment add div, It might works.
-> And if You want Fragment then:
<React.Fragment key={note.id}>
<div key={note.id}>
<Note
key={note.id}
id={note.id}
title={note.title}
text={note.text}
date={note.date}
deleteNote={deleteNote}
closeNote={closeModal}
openModal={openModal}
modalIsOpen={modalIsOpen}
/>
</div>
The keys are to be added to the outermost element returned from the map
Here in your e.g its the fragment <>, to add the key to the fragment you should be using <React.Fragment> for shorthand as shorter syntax doesn't support keys
{notes.map((note) => (
<React.Fragment key={note.id}>
<Note
key={note.id}
id={note.id}
title={note.title}
text={note.text}
date={note.date}
deleteNote={deleteNote}
closeNote={closeModal}
openModal={openModal}
modalIsOpen={modalIsOpen}
/>
</React.Fragment>
))}
These other answers are fine, but to ensure every key is unique do not use a numerical key. It's better to use a combination of text and numbers for your keys or, even better, a short id - https://www.npmjs.com/package/shortid
<Note
key={`note-${note.id}`}
id={note.id}
title={note.title}
/>
https://reactjs.org/docs/lists-and-keys.html#keys

How to get the returned string in class component (using react-video-thumbnail-image package)

This package can return the base64 string with prop renderThumbnailHtml={false}
<VideoImageThumbnail
videoUrl="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
thumbnailHandler={(thumbnail) => console.log(thumbnail)}
width={120}
height={80}
alt="my test video"
/>
but when I place it into img
<img src={`${(
<VideoImageThumbnail
videoUrl="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
thumbnailHandler={(thumbnail) => console.log(thumbnail)}
renderThumbnailHtml={false}
width={120}
height={80}
alt="my test video"
/>
)}`}
alt="test"
/>
it just return [Object object] instead of the base64 string.
I stuck on this 3 days already...and don't know what keyword I can google for these kind of issue.
here is the codeSandBox showing the issue:
https://codesandbox.io/s/vigilant-joliot-2yqvv6?file=/src/App.js
Thanks a lot
You can use the state variable for your thumbnail and update it when the VideoImageThumbnail is rendered. Something like this.
const [thumbnail, setThumbnail] = useState("");
return (
<div className="App">
<h2>DirectOutput</h2>
<VideoImageThumbnail
videoUrl="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
thumbnailHandler={(t) => {
setThumbnail(t);
}}
width={120}
height={80}
alt="my test video"
/>
<h2>Use as an img src</h2>
<img src={thumbnail} alt="test" />
</div>
);

React removes key from my div and then throws error because of that

I have a react func component that is simly returns this:
<div name={id} key={id}>{id}</div>
Problem I have is that when I use this component like so:
{Object.keys(data).map(key => (
<MyComponent id={key} data={data[key]} />
))}
I get error Warning: Each child in a list should have a unique "key" prop. and when I look at generated html it has no key.
<div name="7987">7987</div>
<div name="21727">21727</div>
<div name="157119">157119</div>
<div name="232881">232881</div>
So the question is why is key removed and warning as error is generated?
the react compiler wants the key prop in
<MyComponent id={key} data={data[key]} />
rather than
<div name={id} key={id}>{id}</div>
one way to avoid this is
<MyComponent id={key} data={data[key]} key={key} />
or to make sure there are no duplicate keys
{Object.keys(data).map((key, index) => (
<MyComponent id={key} data={data[key]} key={index} />
))}
keys are not rendered in actual dom. The reason you're getting that error is that you didn't pass the key to MyComponent
So it should be something like this.
{Object.keys(data).map(key => (
<MyComponent key={key} id={key} data={data[key]} />
))}
Make sure keys are not duplicated.
You can also pass index like this to avoid any duplicate.
{Object.keys(data).map((key, index)=> (
<MyComponent key={index} id={key} data={data[key]} />
))}

How to display different tooltip text while mapping over a list?

I am looping over a list and I want to add different tooltip text to different icons, but not exactly sure how to do it. Here's what I have so far:
<React.Fragment key={sv.key}>
<WedgeContainer>
<Button variant="icon" onClick={() => openView(sv)} disabled={sv.disabled || !item.canEdit}>
<Tooltip content="Hello">
<Icon iconId={sv.iconId} size="medium" cursor="pointer" color={theme.font.color.primaryDark} />
</Tooltip>
</Button>
{ !!sv.count && (<Badge borderColor={theme.color.alert} color={theme.color.alert} top="-3rem" right="-1.5rem" content={sv.count}/>) }
<Wedge />
</WedgeContainer>
<Spacer width="4rem" />
</React.Fragment>
))}
And this is what I'm trying to achieve:
You can create an array outside of your loop. In my example i'm using the index to access the items, but in your case you can be creative and do it the way it suits best.
const tooltipContent = [
'tooltip1',
'tooltip2',
'tooltip3',
]
<React.Fragment key={sv.key}>
<WedgeContainer>
<Button variant="icon" onClick={() => openView(sv)} disabled={sv.disabled || !item.canEdit}>
<Tooltip content={tooltipContent[index]}>
<Icon iconId={sv.iconId} size="medium" cursor="pointer" color={theme.font.color.primaryDark} />
</Tooltip>
</Button>
{ !!sv.count && (<Badge borderColor={theme.color.alert} color={theme.color.alert} top="-3rem" right="-1.5rem" content={sv.count}/>) }
<Wedge />
</WedgeContainer>
<Spacer width="4rem" />
</React.Fragment>
))}
If the message is in one of your 'sv' items you can simply pass sv.x to tooltip content instead.

admin-on-rest toggle menu (show / hide)

I'm using admin-on-rest in my react application as admin interface.
My problem is the menu, I'm add a DashboardMenuItem to toggle (show/hide) the menu. But I have no idea what the onClick function should look like and I find no example of this in the documentary or somewhere else.
Can anyone help me by giving an example for this?
My Code:
const Menu = ({ hasDashboard, onMenuTap, resources, translate, logout }) => (
<div style={styles.main}>
<WithPermission value='ROLE_SA'>
{hasDashboard && <DashboardMenuItem onClick={onMenuTap} />}
</WithPermission>
{resources
.filter(r => r.list)
.map(resource => (
<MenuItemLink
key={resource.name}
to={`/${resource.name}`}
primaryText={translatedResourceName(resource, translate)}
leftIcon={<resource.icon />}
onClick={onMenuTap}
/>
))}
{/* <MenuItemLink primaryText='Reports' key='reports' to={`/reports`} leftIcon={<UserIcon />} onClick={onMenuTap} /> */}
<WithPermission value='ROLE_SA'>
<SelectField floatingLabelText='Language for Datasets' onChange={LocaleSwitcher}>
<MenuItem value={'de'} primaryText='DE' />
<MenuItem value={'en'} primaryText='EN' />
</SelectField>
</WithPermission>
{logout}
<img src={Logo} style={{maxWidth: '100%', margin: '0 auto'}} />
</div>
)

Resources