javascript - Storybook react-native 检查 `CellRenderer` 的渲染方法
问题描述
元素类型无效:应为字符串(用于内置组件)或类/函数(用于复合组件)但得到:未定义。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。
检查
CellRenderer
.错误:元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。
检查
CellRenderer
.at createFiberFromTypeAndProps (react-dom.development.js:23965) at createFiberFromElement (react-dom.development.js:23988) at createChild (react-dom.development.js:13628) at reconcileChildrenArray (react-dom.development.js:13900) at reconcileChildFibers (react-dom.development.js:14305) at reconcileChildren (react-dom.development.js:16762) at updateHostComponent (react-dom.development.js:17302) at beginWork (react-dom.development.js:18627) at HTMLUnknownElement.callCallback (react-dom.development.js:188) at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
我正在尝试在应该适用于 react-native ios、android 和 web 的组件上使用故事书。
在这种情况下,我们可以在 Storybook 上尝试 web 部件,它似乎可以工作,但问题是当我放一个图标时,它给了我上面列出的问题。
在 obj in date 中按以下方式插入图标:
icon: (item, background) => Icon ({icon: 'user', item, background})
你能帮我个忙吗?
import React from 'react'
import { View } from 'react-native'
import { storiesOf } from '@storybook/react-native'
import { withKnobs, object } from '@storybook/addon-knobs'
import Dashboard from '../Dashboard'
import { FontAwesome } from 'react-native-vector-icons'
const Icon = ({ icon, item, background }) => (
<FontAwesome
name={icon}
size={40}
color={item.iconColor || (!item.background || !background ? '#3498db' : '#fff')}
style={item.styleIcon}
/>
)
const data = [
{
name: 'Me',
background: '#3498db',
icon: (item, background) => Icon({ icon: 'user', item, background }),
iconColor: '#0d47a1',
rippleColor: '#000',
},
{
name: 'Family',
background: '#b71c1c',
//icon: (item, background) => Icon({ icon: 'gratipay', item, background }),
styleIcon: { color: '#0d47a1' },
},
{
name: 'Lovely',
background: '#ffeb3b',
//icon: (item, background) => Icon({ icon: 'heart', item, background }),
},
{
name: 'Team',
background: '#4caf50',
//icon: (item, background) => Icon({ icon: 'users', item, background }),
styleName: { color: '#0d47a1', fontWeight: 'bold' },
},
{
name: 'Friends',
nameColor: '#3498db',
background: '#02cbef',
//icon: (item, background) => Icon({ icon: 'group', item, background }),
},
{
name: 'Calendars',
background: '#ff5722',
//icon: (item, background) => Icon({ icon: 'calendar', item, background }),
},
]
const card = ({ name }) => console.log('Card: ' + name)
storiesOf('Dashboard', module)
.addDecorator(withKnobs)
.add('example', () => (
<View style={{ alignItems: 'center' }}>
<Dashboard data={data} background={true} card={card} column={2} rippleColor={'#3498db'} />
</View>
))
仪表板.js
import React, { useState } from 'react'
import { Text, View, StyleSheet, Dimensions, Platform, TouchableNativeFeedback, TouchableOpacity } from 'react-native'
import { FlatGrid } from 'react-native-super-grid'
const { width } = Dimensions.get('window')
const RippleColor = (...args) => (Platform.Version >= 21 ? TouchableNativeFeedback.Ripple(...args) : null)
const Touchable = Platform.OS === 'web' ? TouchableOpacity : TouchableNativeFeedback
function Dashboard({ column = 2, data = [], card = () => {}, background, rippleColor = '#fff', ...props }) {
const [state, setState] = useState({
widthDevice: width,
})
const { widthDevice } = state
const onLayout = (e) => {
const { width: widthDevice } = Dimensions.get('window')
setState((prev) => ({ ...prev, widthDevice }))
}
var dim = widthDevice / column - 20
return (
<View onLayout={onLayout} style={{ flex: 1 }}>
<FlatGrid
itemDimension={dim}
data={data}
style={styles.gridView}
renderItem={({ item, index }) => (
<Touchable
onPress={() => card(item)}
delayPressIn={0}
delayPressOut={0}
useForeground={true}
background={RippleColor(item.rippleColor || rippleColor)}
>
<View
style={[
styles.itemContainer,
{
backgroundColor: !item.background || !background ? '#fff' : item.background,
height: dim,
},
]}
>
{item?.icon && item?.icon(item, background)}
<Text
style={[
styles.itemName,
{
color: item.nameColor || (!item.background || !background ? '#000' : '#fff'),
},
item.styleName,
]}
>
{item.name || index}
</Text>
</View>
</Touchable>
)}
{...props}
/>
</View>
)
}
const styles = StyleSheet.create({
gridView: {
flex: 1,
},
itemContainer: {
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
},
itemName: {
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
},
})
export default Dashboard
Webback.config.js
const path = require('path')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
template: path.resolve(__dirname, './public/index.html'),
filename: 'index.html',
inject: 'body',
})
module.exports = {
entry: path.join(__dirname, 'index.web.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, '/build'),
},
resolve: {
alias: {
'react-native$': 'react-native-web',
'@storybook/react-native': '@storybook/react',
'styled-components/native': 'styled-components',
},
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules[/\\](?!react-native-vector-icons)/,
use: {
loader: 'babel-loader',
options: {
// Disable reading babel configuration
babelrc: false,
configFile: false,
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-flow',
'@babel/preset-typescript',
{
plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread'],
},
],
},
},
},
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules[/\\](?!react-native-super-grid)/,
use: {
loader: 'babel-loader',
options: {
// Disable reading babel configuration
babelrc: false,
configFile: false,
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-flow',
'@babel/preset-typescript',
{
plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread'],
},
],
},
},
},
{
test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'file-loader',
},
{
test: /\.ttf$/,
loader: 'url-loader', // or directly file-loader
include: path.resolve(__dirname, 'node_modules/react-native-vector-icons'),
},
],
},
plugins: [HTMLWebpackPluginConfig],
devServer: {
historyApiFallback: true,
contentBase: './',
hot: true,
},
}
解决方案
推荐阅读
- json - axios发布请求未映射到Requestbody中的java对象属性
- reactjs - 无法导航到其他组件
- android - 通过intent-Android打开地图以显示当前位置的方向
- android - 需要在 Android Studio 中手动输入密钥库详细信息,即使它们存在于 build.gradle 中
- wordpress - 带有 ACF 字段的 Wordpress 查询附件
- amazon-web-services - 是否可以通过 SSH 连接到 FARGATE 托管容器实例?
- python - 使用 apply_async 写入文件
- html - Firefox 上的动画不起作用(仅限 CSS)
- java - ArrayList 打印重复元素
- c# - UpdatePanel 中的列表框不会第二次触发