javascript React:如何检查收到的道具是否未定义?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48789492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 08:16:42  来源:igfitidea点击:

React: How to check if received props are undefined?

javascriptreactjs

提问by Enoy

Hello and thank you for your time:

您好,感谢您的时间:

I am following the following tutorial:https://app.pluralsight.com/library/courses/react-flux-building-applications/table-of-contents

我正在学习以下教程:https: //app.pluralsight.com/library/courses/react-flux-building-applications/table-of-contents

And currently I have detected that when you try to create an author, it tries to load current's author's URL's author id. Because of it is being created, it is undefined, and so then the create author functionality does not work.

目前我已经检测到,当您尝试创建作者时,它会尝试加载当前作者的 URL 的作者 ID。因为它正在被创建,它是未定义的,因此创建作者功能不起作用。

I have read some topics about checking undefined type both in JS and React: How to determine if variable is 'undefined' or 'null'?

我已经阅读了一些关于在 JS 和 React 中检查未定义类型的主题: 如何确定变量是“未定义”还是“空”?

Checking for Undefined In React

在 React 中检查未定义

https://github.com/facebook/react/issues/3725

https://github.com/facebook/react/issues/3725

And I have tried the following:

我尝试了以下方法:

In manageAuthorForm we pass in to the authorForm the author's state:

在 manageAuthorForm 中,我们将作者的状态传递给 authorForm:

  render() {
        return (
            <AuthorForm author={this.state.author}
                        onChange={this.setAuthorState}
                        onSave={this.saveAuthor}/>
        );
    };

And then I have tried into the AuthorForm:

然后我尝试进入 AuthorForm:

import React from 'react';
import {Input} from "../common/textInput";
import Link from "react-router-dom/es/Link";

class AuthorForm extends React.Component {
    componentWillReceiveProps(nextProps) {
        if (nextProps.state.author === undefined) {
            this.props.author = {
                author: {
                    id: '',
                    firstName: '',
                    lastName: '',

                }
            };
        }
    }

    render() {
        return (
            <form>
                <h1>Manage author</h1>
                <Input
                    name="firstName"
                    label="First Name"
                    value={this.props.author.firstName}
                    onChange={this.props.onChange}
                />

                <Input
                    name="lastName"
                    label="Last Name"
                    value={this.props.author.lastName}
                    onChange={this.props.onChange}
                />

                <button type="submit" value="Save" className="btn btn-default" onClick={this.props.onSave}><Link
                    to="/authors">Save
                    author</Link>
                </button>
            </form>
        );
    }
}

export {AuthorForm}

And it reports that nextProps are undefined:

它报告 nextProps 未定义:

Uncaught TypeError: Cannot read property 'author' of undefined
    at AuthorForm.componentWillReceiveProps (authorForm.js:7)
    at callComponentWillReceiveProps (react-dom.development.js:6389)
    at updateClassInstance (react-dom.development.js:6575)
    at updateClassComponent (react-dom.development.js:7848)
    at beginWork (react-dom.development.js:8225)
    at performUnitOfWork (react-dom.development.js:10224)
    at workLoop (react-dom.development.js:10288)
    at HTMLUnknownElement.callCallback (react-dom.development.js:542)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:581)
    at invokeGuardedCallback (react-dom.development.js:438)
    at renderRoot (react-dom.development.js:10366)
    at performWorkOnRoot (react-dom.development.js:11014)
    at performWork (react-dom.development.js:10967)
    at requestWork (react-dom.development.js:10878)
    at scheduleWorkImpl (react-dom.development.js:10732)
    at scheduleWork (react-dom.development.js:10689)
    at scheduleTopLevelUpdate (react-dom.development.js:11193)
    at Object.updateContainer (react-dom.development.js:11231)
    at react-dom.development.js:15226
    at Object.unbatchedUpdates (react-dom.development.js:11102)
    at renderSubtreeIntoContainer (react-dom.development.js:15225)
    at Object.render (react-dom.development.js:15290)
    at Object../src/index.js (index.js:17)
    at __webpack_require__ (bootstrap 78b34f0f34b98a41c613:678)
    at fn (bootstrap 78b34f0f34b98a41c613:88)
    at Object.0 (authorStore.js:39)
    at __webpack_require__ (bootstrap 78b34f0f34b98a41c613:678)
    at bootstrap 78b34f0f34b98a41c613:724
    at bootstrap 78b34f0f34b98a41c613:724
componentWillReceiveProps @ authorForm.js:7
callComponentWillReceiveProps @ react-dom.development.js:6389
updateClassInstance @ react-dom.development.js:6575
updateClassComponent @ react-dom.development.js:7848
beginWork @ react-dom.development.js:8225
performUnitOfWork @ react-dom.development.js:10224
workLoop @ react-dom.development.js:10288
callCallback @ react-dom.development.js:542
invokeGuardedCallbackDev @ react-dom.development.js:581
invokeGuardedCallback @ react-dom.development.js:438
renderRoot @ react-dom.development.js:10366
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
requestWork @ react-dom.development.js:10878
scheduleWorkImpl @ react-dom.development.js:10732
scheduleWork @ react-dom.development.js:10689
scheduleTopLevelUpdate @ react-dom.development.js:11193
updateContainer @ react-dom.development.js:11231
(anonymous) @ react-dom.development.js:15226
unbatchedUpdates @ react-dom.development.js:11102
renderSubtreeIntoContainer @ react-dom.development.js:15225
render @ react-dom.development.js:15290
./src/index.js @ index.js:17
__webpack_require__ @ bootstrap 78b34f0f34b98a41c613:678
fn @ bootstrap 78b34f0f34b98a41c613:88
0 @ authorStore.js:39
__webpack_require__ @ bootstrap 78b34f0f34b98a41c613:678
(anonymous) @ bootstrap 78b34f0f34b98a41c613:724
(anonymous) @ bootstrap 78b34f0f34b98a41c613:724

And in the web browser it reports:

并在网络浏览器中报告:

×
TypeError: Cannot read property 'author' of undefined
AuthorForm.componentWillReceiveProps
C:/Users/YonePC/WebstormProjects/flux/src/components/authors/authorForm.js:7
   4 | 
   5 | class AuthorForm extends React.Component {
   6 |     componentWillReceiveProps(nextProps) {
>  7 |         if (nextProps.state.author === undefined) {
   8 |             this.props.author = {
   9 |                 author: {
  10 |                     id: '',
View compiled
? 15 stack frames were collapsed.
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser's developer console to further inspect this error.

The full code, in github: https://github.com/YoneMoreno/ReactFluxAuthorsPageTutorial

完整代码,在github:https: //github.com/YoneMoreno/ReactFluxAuthorsPageTutorial

Could you help me, please?

请问你能帮帮我吗?

Thank you ;=)

谢谢;=)

采纳答案by Mayank Shukla

Simple solution will be:

简单的解决方案是:

<AuthorForm 
   author={this.state.author || {firstName:'', lastName:'', id:''}}
   ...
/>

And remove the componentWillReceivePropsmethod from child component.

componentWillReceiveProps从子组件中删除该方法。

Better approachwill be:

更好的方法是:

1-Either assign the initial value of authorin state as:

1-将状态的初始值分配author为:

this.state = {
   author: {firstName:'', lastName:'', id:''}
}

2-Or inside render method of child component, write it like this:

2-或者在子组件的 render 方法中,这样写:

render(){

   const {firstName='', lastName='', id=''} = this.props.author || {};

   return(....)
}

And use firstName, lastName, iddirectly instead of this.props.

firstName, lastName, id直接使用而不是this.props.



Issues in your code:

您的代码中的问题:

1- It should be nextProps.authorinstead of nextProps.state.authorin componentWillReceivePropslifecycle method.

1-应当nextProps.author代替nextProps.state.authorcomponentWillReceiveProps生命周期方法。

2- Props are read-only, Whether you declare a component as a function or a class, it must never modify its own props. You are trying to change the value in componentWillReceiveProps.

2- props 是只读的,无论你将组件声明为函数还是类,它都不能修改自己的 props。您正在尝试更改 中的值componentWillReceiveProps

回答by Carol Chen

Your error message is; Cannot read property 'author' of undefined

您的错误信息是; Cannot read property 'author' of undefined

It is actually not authorthat is undefined but nextProps.state. nextPropsis an object containing the contents of onlythe props.

实际上不是authorundefined 而是nextProps.state. nextProps是一个包含 props内容的对象。

The other problem here is that componentWillReceiveProps()is not called when when mounting, thus if props.authoris initially undefined then that error handling won't work. Mayank Shukla has a good answer, however that requires you to have a constructor like so;

这里的另一个问题是componentWillReceiveProps()在安装时不会调用它,因此如果props.author最初未定义,则错误处理将不起作用。Mayank Shukla 有一个很好的答案,但这需要你有一个像这样的构造函数;

constructor(props) {
    super(props);
    this.state = {
      author: this.props.author,
    };
}

Since props cannot be updated, it makes more sense to put it in the state so that it can be in the future. If you need to receive prop updates, use setState()in componentWillUpdate()

由于 props 无法更新,因此将其放在 state 中以便将来可以使用更有意义。如果你需要得到道具更新,使用setState()componentWillUpdate()

Another, more long winded solution would be to make authora required prop, and not attempt to create that component until the necessary props exist. This is also better practice.

另一个更冗长的解决方案是制作author一个必需的道具,并且在必要的道具存在之前不要尝试创建该组件。这也是更好的做法。

AuthorForm.propTypes = {
  author: PropTypes.string.isRequired,
};

回答by Yoan

nextProps.state ?

nextProps.state ?

The one that has a state it is the component, Please decide where are you going to handle the authordata. In the component props or in the state.

具有状态的组件是组件,请决定您将在哪里处理author数据。在组件 props 或 state 中。

Besides that you should take a look of: https://www.npmjs.com/package/prop-types

除此之外你应该看看:https: //www.npmjs.com/package/prop-types

Its a library for react to handle types and default values for your component props. With this library you are going to be able to do somethings like:

它是一个用于处理组件 props 的类型和默认值的库。使用此库,您将能够执行以下操作:

FunctionPointAutomatedTable.defaultProps = {
  dataSource: [],
};

FunctionPointAutomatedTable.propTypes = {
  applicationId: PropTypes.string,
  functionType: PropTypes.string,
  dataSource: PropTypes.array,
  allowedTypes: PropTypes.array,
  onEdit: PropTypes.func,
  onDelete: PropTypes.func,
  onIgnore: PropTypes.func,
  onMerge: PropTypes.func,
  onUnmerge: PropTypes.func,
};

回答by Янов Алексей

const UndefinedCheck =  data => {
    if(data === undefined){
        return 1
    }else {
        return data
    }
}

export default UndefinedCheck

回答by stadnik0ff

You should setUp default values to {this.state.author} which you set to component instead of setting default values to props into

您应该将默认值设置为 {this.state.author} 并将其设置为 component 而不是将默认值设置为 props