react got error of unknown props - javascript

I want to try stateless component in react, I split them into 2, but I got error of Warning: Unknown propsitemson <renderItems> tag
What's wrong with my code below?
import Items from './Items'
import Infinite from 'react-infinite'
const LeftPanel = (props) => {
return(
<div className="leftPanel">
<renderItems {...props} />
</div>
)
}
const renderItems = (props) => (
<Infinite containerHeight={200} elementHeight={118}>
{map(props.items, (item, index) => (
<Items
index={index}
item={item}
/>
))}
</Infinite>
)
export default LeftPanel

I think you should rename your renderItems to RenderItems.
I was seeing this and it looks like in JSX you need to put capital letter on the first word of your component name:
<component /> compiles to React.createElement('component') (html tag)
<Component /> compiles to React.createElement(Component)

There's a syntactic error in your code. You're using parenthesis in your functional component instead of curly braces.
const renderItems = (props) => {
return (<Infinite containerHeight={200} elementHeight={118}>
{map(props.items, (item, index) => (
<Items
index={index}
item={item}
/>
))}
</Infinite>);
}
Furthermore, lowercase component names are now deprecated so renderItems should be called RenderItems.

Related

Creating generic components in React Javascript

I'm trying to build a React select component that can support multiple different child component types.
I'd like to do something like this:
export const GenericSelect = (props) => {
const { component, items } = props;
return <>{items && items.map((item, index) => <component id={items.id} name={item.name} />)}</>;
};
And then be able to use it like:
<GenericSelect component={NonGenericCard} items={items} />
Where NonGenericCard supports a fixed set of properties (e.g., id, name), which will be populated from values in the items object.
I tried this, but it doesn't seem like it can create the <component/> at run-time.
Is this possible in Javascript? If so, how can it be accomplished?
In JSX, lower-case tag names are considered to be HTML tags. So you should use Component instead of component.
Also id should be item.id instead of items.id and you should give each element a key.
export const GenericSelect = (props) => {
const { Component, items } = props;
return (
<>
{items &&
items.map((item, index) => (
<Component key={item.id} id={item.id} name={item.name} />
))}
</>
);
};
<GenericSelect Component={NonGenericCard} items={items} />
https://reactjs.org/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized

Each child in a list should have a unique "key" prop. I made it, but still see this error

I know about key prop, so i made it in listitem component
const ListItem = ({item}) => {
const {result, time, id} = item;
return(
<li key={id} className='list__item'>
<span className='item__result'>{result} cps</span>
<span className='item__date'>{time}</span>
<button className='item__delete'>delete</button>
</li>
)}
And here is component, where I use it
const Leadboard = () => {
const [data, setData] = useState([{result:'5,63', time:'08.06.2022', id: (new Date()).toString(16)}, {result:'5,63', time:'08.06.2022', id: +(new Date() - 1)}, {result:'5,63', time:'08.06.2022', id: +(new Date() - 2)}]);
let elements=data.map(item => {
return (
<>
<ListItem item={item} />
</>
)
});
return(
<div className='app-leadboard'>
<span className='app-leadboard__title'>Your's best results:</span>
<ol className='app-leadboard__list' type='1'>
{elements}
</ol>
</div>
)}
But after render I still see "key prop" error
I spent so much time on this, but can't understand what's wrong. So smb, help pls with it
You’ve got the wrong list. It’s the <ListItem> components that need the key. (And you can get rid of the react fragments around them because they are pointless).
React first accesses the empty bracket (<> </> ) before accessing the key attribute in your child component.
So you need to either
Make use of the empty brackets and pass the key attribute to it
// Use React.Fragment
let elements=data.map(item => { return
(
<React.Fragment key={item.id}>
<ListItem item={item} />
</React.Fragment>
)
});
and remove the key in the child (ListItem) component
ListItem.js
<li
/* Remove this
key={id}
*/
className='list__item'>
OR
Get rid of the empty brackets (<> </>) and reference the child's component directly.
let elements=data.map(item => {
return (<ListItem item={item} />)
});
and leave the key attribute in the child component
More on React Fragment. React Official Docs

How can I pass a ref to a react-native-reanimated component?

I'm trying to pass a ref to a component with a similar approach to the following code block, but the current value always returns undefined. This approach works fine with a plain FlatList from react-native, however it doesn't work once I'm using either an Animated.FlatList or an Animated.createAnimatedComponent(FlatList) :
const Parent = () => {
const flatListRef = useRef();
useEffect(() => {
console.log(flatListRef.current) // undefined
})
return (
<View>
<Child ref={flatListRef} />
</View>
)
}
const Child = React.forwardRef((props, ref) => {
return (
<Animated.FlatList
ref={ref}
/>
)
})
The library react-native-reanimated works a little bit different in comparison to react-native-animated.
If we create the animated component via Animated.createAnimatedComponent(FlatList), then everything works as expected.
Here is a working version of your code. I have logged the function scrollToIndex of the FlatList ref for testing purposes.
import Animated from "react-native-reanimated"
const ReanimatedFlatList = Animated.createAnimatedComponent(FlatList);
const Parent = (props) => {
const flatListRef = useRef(null);
useEffect(() => {
console.log(flatListRef.current.scrollToIndex)
}, [])
return (
<View>
<Child ref={flatListRef} />
</View>
)
}
const Child = React.forwardRef((props, ref) => {
return (
<ReanimatedFlatList
ref={ref}
/>
)
})

Wrapping props component in React js

I have prop 'drawerComponent' which goes in Drawer prop 'component'
This code works fine.
render() {
return(
<Drawer component={this.props.drawerComponent} />
)
}
But if I try to wrap drawerComponent by other one it fails. I get 'Element type error' or drawerComponent is not rendering
render() {
const Wrapper = (props) => <div>{this.props.drawerComponent}</div>
return(
<Drawer component={() => <Wrapper drawerComponent={this.props.drawerComponent} />} />
)
}
What's wrong with it?
You Drawer component accepts a component instance and not a component, you can simply write the wrapper like
render() {
const Wrapper = (props) => <div>{props.drawerComponent}</div>
return(
<Drawer component={<Wrapper drawerComponent={this.props.drawerComponent} />} />
}

How to do conditional check twice in React component

I have a React component as shown. I am passing prop hasItems and based on this boolean value, i am showing PaymentMessage Component or showing AddItemsMessage component.
export const PayComponent = ({
hasItems
}: props) => {
return (
<Wrapper>
{hasItems ? (
<PaymentMessage />
) : (
<AddItemsMessage />
)}
<Alerts
errors={errors}
/>
</Wrapper>
);
};
This works well. Now, i need to pass another prop (paymentError). So based on this, i modify the JSX as below. I will highlight the parts i am adding by using comment section so it becomes easy to see.
export const PayComponent = ({
hasItems,
paymentError //-----> added this
}: props) => {
return (
<Wrapper>
{!paymentError ? ( //----> added this. This line of code errors out
{hasItems ? (
<PaymentMessage />
) : (
<AddItemsMessage />
)}
):( //-----> added this
<Alerts
errors={errors}
/>
) //-----> added this
</Wrapper>
);
};
Basically, i am taking one more input prop and modifying the way my JSX should look. But in this case, i am not able to add one boolean comparison one after the error. How do i make it working in this case. Any suggestions please ???
I recommend you to create a function to handle this behavior. It's easier to read and to mantain
export const PayComponent = ({
hasItems,
paymentError
}: props) => {
const RenderMessage = () => {
if (hasItems) {
if (paymentError) {
return <PaymentMessage />
}
return <AddItemsMessage />
}
return <Alerts errors={errors}/>
};
return (
<Wrapper>
<RenderMessage />
</Wrapper>
);
};

Categories

Resources