我正在使用名为react-window 的库
当我像这样将道具传递给它的行时:
{Row({...props, {otherProps}})}
它给了我一个类似的错误:
React.createElement: type is invalid -- 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:...
正确的方法是如何做到这一点?
我正在使用名为react-window 的库
当我像这样将道具传递给它的行时:
{Row({...props, {otherProps}})}
它给了我一个类似的错误:
React.createElement: type is invalid -- 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:...
正确的方法是如何做到这一点?
您将道具添加到父元素的数据属性。注意itemData={{ testData: "123", otherData: true }}
。
const Example = () => (
<AutoSizer>
{({ height, width }) => (
<List
className="List"
height={height}
itemCount={1000}
itemSize={35}
width={width}
itemData={{ testData: "123", otherData: true }}
>
{Row}
</List>
)}
</AutoSizer>
);
然后在 Row 组件中,您可以从这样的道具中获取数据const { data, index, style } = props;
const Row = props => {
const { data, index, style } = props;
return (
<div>
{index} Row {data.testData}
</div>
);
};
演示以查看它的实际效果:https ://codesandbox.io/s/bvaughnreact-window-fixed-size-list-vertical-dtnre
这也有效:
<List
...
>
{(props) => Row({...props, yourCustomProp})}
</List>
像这样在行中使用:
const Row = props => {
console.log(props.yourCustomProp);
return (
<div>
...
</div>
);
};
您可以Row
返回一个函数。您可以从函数定义中访问这两个参数。因此,您可以将数据直接传递到Row()
调用中。
const Example = () => (
<AutoSizer>
{({ height, width }) => (
<List
className="List"
height={height}
itemCount={1000}
itemSize={35}
width={width}
>
{Row({ testData: "123", otherData: true })}
</List>
)}
</AutoSizer>
);
和Row
功能:
const Row = data => props => {
const { index, style } = props;
return (
<div>
{index} Row {data.testData}
</div>
);
};
这是一个演示:https ://codesandbox.io/s/bvaughnreact-window-fixed-size-list-vertical-tqdpf
我发现这非常令人困惑,但这是我的代码(希望它可以提供帮助):
class Row extends PureComponent {
render() {
const { data, index, style } = this.props
const {
classes,
itemsPerRow,
shows,
setCardMarkerHover,
resetCardMarkerHover,
playTrack,
} = data
const items = []
const fromIndex = index * itemsPerRow
const toIndex = Math.min(fromIndex + itemsPerRow, shows.length)
//console.log(this.props)
for (let i = fromIndex; i < toIndex; i++) {
items.push(
<ShowCard
key={i}
item={shows[i]}
setCardMarkerHover={setCardMarkerHover}
resetCardMarkerHover={resetCardMarkerHover}
playTrack={playTrack}
/>
)
}
// console.log(items)
return (
<div className={classes.Row} style={style}>
{items}
</div>
)
}
}
class FastList extends React.Component {
getItemData = memoize(
(
classes,
itemsPerRow,
shows,
setCardMarkerHover,
resetCardMarkerHover,
playTrack
) => ({
classes,
itemsPerRow,
shows,
setCardMarkerHover,
resetCardMarkerHover,
playTrack,
})
)
render() {
const {
shows,
classes,
setCardMarkerHover,
resetCardMarkerHover,
playTrack,
} = this.props
//console.log(this.props)
// console.log(shows);
return (
<div style={{ height: "90vh", minWidth: "20vw" }}>
<AutoSizer>
{({ height, width }) => {
const itemsPerRow = 1
const rowCount = Math.ceil(shows.length / itemsPerRow)
const itemData = this.getItemData(
classes,
itemsPerRow,
shows,
setCardMarkerHover,
resetCardMarkerHover,
playTrack
)
return (
<div>
<List
height={height}
itemCount={rowCount}
itemData={itemData}
itemSize={CARD_SIZE}
width={width}
>
{Row}
</List>
</div>
)
}}
</AutoSizer>
</div>
)
}
}
FastList.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(FastList)
import { CSSProperties, memo, useCallback, useMemo } from 'react'
import AutoSizer from 'react-virtualized-auto-sizer'
import { areEqual, FixedSizeList } from 'react-window'
interface Data {
someProp: string
users: Array<{ id: number }>
someMethod(id: number): string
}
interface RowProps {
data?: Data
index?: number
style?: CSSProperties
}
const Row = memo((props: RowProps) => {
const { data, index, style } = props
const { someProp, users, someMethod } = data || {}
const { id } = users[index] || {}
return (
<div style={style}>
{someProp}: {someMethod(id)}
</div>
)
}, areEqual)
interface ComponentProps {
someProp: string
users: Array<{ id: number }>
}
const SomeComponent = (props: ComponentProps) => {
const { someProp, users } = props
const someMethod = useCallback(
(id: number) => {
return `${someProp.slice(-4)}-${id}`
},
[someProp],
)
const itemData = useMemo(
() => ({
someProp,
users,
someMethod,
}),
[someProp, users, someMethod],
)
return (
<AutoSizer disableWidth>
{({ height }) => (
<FixedSizeList
itemCount={users.length}
itemData={itemData}
itemSize={48}
height={height}
width={'100%'}
>
{Row}
</FixedSizeList>
)}
</AutoSizer>
)
}
这是Function as Child Component
模式。查看更多:这里
其他选择:
<List
itemData={{
...yourProps
}}>
...
>
{(props) => <Row {...props}/>}
</List>
排
const Row = ({ data, index, style }) => {
const { ...yourProps } = data
return (
<div style={style}> // Don't forget to pass the style
...
</div>
);
};