简体   繁体   English

尝试呈现 JSX 元素但未定义

[英]Attempting to render JSX element but getting undefined

So I have this JSX element that I am attempting to render in the Class component.所以我有这个 JSX 元素,我试图在 Class 组件中呈现。 It is essentially a visual provided by D3's React library.它本质上是 D3 的 React 库提供的视觉效果。 However, I am receiving this error upon attempting to render the D3 visual:但是,我在尝试渲染 D3 视觉效果时收到此错误:

Unhandled Rejection (Error): Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Below are some relevant code snippets of where the error is occurring:以下是错误发生位置的一些相关代码片段:

The builder function to pass all the necessary props to the D3 library构建器 function 将所有必要的道具传递给 D3 库

const buildModelVisual = (dataPoints) => {
    console.log("category: " + dataPoints[0].category)
    console.log("range: " + dataPoints[0].range)
    console.log("frequency: " + dataPoints[0].frequency)
    dataPoints[0].frequency.forEach(f => 
        console.log("f: " + f)
    )
    const width = 960,
        height = 500,
        margins = {top: 50, right: 50, bottom: 50, left: 50},
        id = "model-visual",
        title = "NaiveBayes Model Visual",
        svgClassName = "model-visual-class",
        titleClassName = "model-visual-title-class",
        legendClassName = "model-legend",
        showLegend = true,
        showXAxis = true,
        showYAxis = true,
        showXGrid = false,
        showYGrid = false,
        ranges = [
            ...dataPoints[0].range
        ],
        frequencies = [
            ...dataPoints[0].frequency
        ],
        x = () => {
            return ranges.forEach(r => {
                return r;
            })
        },
        xOrient = 'bottom',
        xTickOrient = 'bottom'
    
    const xDomain = dataPoints[0].range.forEach(r => {
        return {
            category: dataPoints[0].category, range: r
        }
        }),
        xRangeRoundBands = {interval: [0, width - margins.left - margins.right], padding: 0.1},
        xScale = 'ordinal',
        xAxisClassName = 'x-axis',
        xLabel = dataPoints[0].category,
        xLabelPosition = 'bottom',
        xTickPadding = 3,
        xInnerTickSize = 6,
        xOuterTickSize = 6,
        y = () => {
            return frequencies.forEach(freqInRange => {
                return freqInRange.forEach(f => {
                    return f;
                });
            })
        },
        yOrient = 'left',
        yTickOrient = 'left',
        yRange = [height - margins.top - margins.bottom, 0]

    const yDomain = [0, d3.max(
            dataPoints[0].frequency,
            (f) => {
                return f.value
            }
        )],
        yScale = 'linear',
        yAxisClassName = 'y-axis',
        yLabel = "Population",
        yTickFormat = d3.format(".2s"),
        yLabelPosition = 'left',
        yTickPadding = 4,
        yInnerTickSize = 6,
        yOuterTickSize = 6

    return (
        <Chart
        title={title}
        id={id}
        width={width}
        height={height}
        >
        <BarStackChart
          title= {title}
          data= {ranges}
          width= {width}
          height= {height}
          id= {id}
          margins= {margins}
          svgClassName= {svgClassName}
          titleClassName= {titleClassName}
          yAxisClassName= {yAxisClassName}
          xAxisClassName= {xAxisClassName}
          legendClassName= {legendClassName}
          categoricalColors= {d3.scaleOrdinal(d3.schemeCategory10)}
          chartSeries = {ranges}
          showLegend= {showLegend}
          showXAxis= {showXAxis}
          showYAxis= {showYAxis}
          x= {x}
          showXGrid= {showXGrid}
          xDomain= {xDomain}
          xRangeRoundBands= {xRangeRoundBands}
          xScale= {xScale}
          xOrient= {xOrient}
          xTickOrient= {xTickOrient}
          xTickPadding = {xTickPadding}
          xInnerTickSize = {xInnerTickSize}
          xOuterTickSize = {xOuterTickSize}
          xLabel = {xLabel}
          xLabelPosition = {xLabelPosition}
          y= {y}
          showYGrid= {showYGrid}
          yOrient= {yOrient}
          yRange= {yRange}
          yDomain= {yDomain}
          yScale= {yScale}
          yTickOrient= {yTickOrient}
          yTickPadding = {yTickPadding}
          yInnerTickSize = {yInnerTickSize}
          yOuterTickSize = {yOuterTickSize}
          yTickFormat= {yTickFormat}
          yLabel = {yLabel}
          yLabelPosition = {yLabelPosition}
        />
      </Chart>
    )
}

The HO class component that is rendering the graph and the interface正在渲染图形和界面的 HO class 组件

    constructor(props) {
        super(props);
        this.ref = React.createRef();
        this.state = {
            input: "",
            output: [],
            visual: null
        }
    }

REST API call (within the default class Component) that sets the data for the BarStackChart REST API 调用(在默认的 class 组件内)为 BarStackChart 设置数据

callGetModel = () => {
        let getModelRanges = getCall(ApiURL.get_model_ranges);
        let getModelFrequencies = getCall(ApiURL.get_model_frequencies);
        Promise.all([getModelRanges, getModelFrequencies]).then(data => {
            this.setState({output: data})
            const dataPoints = [];

            for (let value in JSON.parse(data[0].toString())) {
                dataPoints.push({
                    category: value,
                    range: JSON.parse(data[0].toString())[value],
                    frequency: JSON.parse(data[1].toString())[value]
                })
            }

            console.log(dataPoints)

            const ModelVisual = buildModelVisual(dataPoints)

            this.setState({ visual: ModelVisual }) // returns JSX element 

            console.log(this.state.visual)
        });
    }

The render method for the class Component class 组件的渲染方法

    render() {
        return <div>
            <h3>Welcome to Naive Bayes Java!</h3>
            <p>The REST API for this project is hosted at</p>
            <a style={{'display':'block', 'paddingBottom':'1.5em', 'color':'rgb(0, 150, 196)'}} href="https://naivebayesjava.herokuapp.com/swagger-ui.html#/">https://naivebayesjava.herokuapp.com/</a>
            <button style={{'display':'inline', 'background':'rgb(32, 32, 32)', 'color':'rgb(190, 190, 190)'}} onClick={this.callListOfFiles}>
                Get List of Valid Files
            </button>
            <button style={{'background':'rgb(32, 32, 32)', 'color':'rgb(190, 190, 190)'}} onClick={this.callGetModel}>
                Get Model
            </button>
            <button style={{'background':'rgb(32, 32, 32)', 'color':'rgb(190, 190, 190)'}} onClick={this.callGetModelAccuracy}>
                Get Model Accuracy
            </button>
            <div style={{'margin':'auto', 'display':'block'}}>
                <input style={{'background':'rgb(32, 32, 32)', 'color':'rgb(190, 190, 190)'}} type='text' value={this.state.input} onChange={this.handleChange}/>
                <button style={{'background':'rgb(32, 32, 32)', 'color':'rgb(190, 190, 190)'}} onClick={this.callSetData}>
                    Set Training Data File
                </button>
            </div>
            {/* <button onClick={this.callGetTrainingData}>
                Get Training Data Arff Files
            </button> */}
            <div style={{'padding-top':'0.5em'}} ref={this.ref}></div>
            <output type='textBox' style={{ 'padding':'1.25em', 'display':'block', 'Height': '30px', 'Width': '300px' }}>
            { Object.keys(this.state.output).map(key => {
                return this.state.output[key]                
            }) }
            </output>
            { this.state.visual }
        </div>
    }

There most definitely is a better way to implement this besides setting a "this.state.visual" JSX Element and calling that in the render method, although as I am really new to both React (started learning about a month ago) and JS (started about 3 months ago) I don't quite know all the common practices with either;除了设置“this.state.visual”JSX 元素并在渲染方法中调用它之外,绝对有更好的方法来实现它,尽管我对 React(大约一个月前开始学习)和 JS(大约 3 个月前开始)我不太了解两者的所有常见做法; just the general theory behind how they work.只是它们工作原理背后的一般理论。

This interface and my portfolio are hosted at joshuabaroni.github.io .这个界面和我的投资组合托管在joshuabaroni.github.io The interface i am attempting to improve is the NaiveBayes Project Interface under the "Projects" section我试图改进的界面是“项目”部分下的 NaiveBayes 项目界面

Any recommendations would be appreciated.任何建议将不胜感激。 the whole JS file is available upon request.整个 JS 文件可应要求提供。

You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.您可能忘记从定义它的文件中导出您的组件,或者您可能混淆了默认导入和命名导入。

You aren't exporting your classes/functions as it is required.您没有按要求导出类/函数。

Exporting without default means it's a "named export".没有默认导出意味着它是“命名导出”。 You can have multiple named exports in a single file.您可以在一个文件中有多个命名导出。 So if you do this,所以如果你这样做,

class Template {}
class AnotherTemplate {}
export { Template, AnotherTemplate } // named export

then you have to import these exports using their exact names.那么您必须使用它们的确切名称导入这些导出。 So to use these components in another file you'd have to do,所以要在另一个文件中使用这些组件,你必须这样做,

import {Template, AnotherTemplate} from './components/templates'

Alternatively if you export as the default export like this,或者,如果您像这样导出为默认导出,

export default class Template {}

Then in another file you import the default export without using the {}, like this,然后在另一个文件中导入默认导出而不使用 {},就像这样,

import Template from './components/templates'

There can only be one default export per file.每个文件只能有一个默认导出。 In React it's a convention to export one component from a file, and to export it is as the default export.在 React 中,从文件中导出一个组件是一种惯例,并且将其导出为默认导出。

You're free to rename the default export as you import it,您可以在导入时自由重命名默认导出,

import TheTemplate from './components/templates'

And you can import default and named exports at the same time,您可以同时导入默认导出和命名导出,

import Template,{AnotherTemplate} from './components/templates'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 根据条件渲染JSX元素 - Render JSX element based on condition 在渲染 function 中调用返回 JSX 元素的函数 - calling functions that return a JSX element in render function 尝试获取用户输入时未定义 - Getting undefined when attempting to get user input 尝试渲染表时,$ .el在骨架-ui.js中未定义 - $.el is undefined in backbone-ui.js when attempting to render table 尝试呈现 Firebase 身份验证详细信息在 React web 应用程序中返回“未定义” - Attempting to render Firebase Auth details returning 'undefined' in React web app 如何在反应中从渲染函数返回一个空的jsx元素? - How to return an empty jsx element from the render function in react? 为什么不能从 2 个 JSX 元素渲染? - Why you can't render from 2 JSX element? 如何渲染jsx元素多于道具项目(数组) - How to render jsx element more than the props items (array) 如何根据条件渲染不同的元素(react jsx) - How to render a different element based on a condition (react jsx) JSX 元素类型 &#39;ReactElement<any> 不是 JSX 元素的构造函数。 类型 &#39;undefined&#39; 不能分配给类型 &#39;Element | 空值&#39; - JSX element type 'ReactElement<any> is not a constructor function for JSX elements. Type 'undefined' is not assignable to type 'Element | null'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM