【问题标题】:React doesn't change render according props invoked after a conditional renderingReact 不会根据条件渲染后调用的道具更改渲染
【发布时间】:2018-03-26 09:37:56
【问题描述】:

我有一个带有条件渲染的组件:'如果该组件有道具“showCross”,则显示一个带有十字的按钮,除非什么都没有'。 一切都很好,当有 showCross 时,就有十字架,除非什么都没有:

import PropTypes from 'prop-types'
import React from 'react'
import {Cell} from 'react-mdl/lib/Grid'

class RefundFormContent extends React.Component {
  render() {
    const { fields, onClose } = this.props
    const style = {width: '150px'}

    function CrossButton(props) {
        let {showCross} = props
        const displayCross =
          showCross ? <button
              className="mdl-button mdl-js-button mdl-button--icon"
              onClick={onClose}
          >x</button>
              : null
        return (
            <div>{displayCross}</div>
        )
    }


    return (
        <React.Fragment>
            <Cell col={3}>
                <Formfield {...fields.type} style={style} />
            </Cell>
            <Cell col={4}>
                <Formfield {...fields.provider} style={style} />
            </Cell>
            <Cell col={4}>
                <Formfield {...fields.amount} style={style} />
            </Cell>
            <Cell col={1} className="mdl-typography--text-right">
                <CrossButton showCross />
            </Cell>
        </React.Fragment>
    )
  }
}

export default RefundFormContent

但问题是当我在另一个组件中使用这个组件时,即使将prop传递给false,十字仍然显示(我想隐藏它):

import PropTypes from 'prop-types'
import React from 'react'
import Grid from 'react-mdl/lib/Grid'
import Form from 'forms/Form'
import {validateCurrency} from 'forms/inputs/currency'
import {makeChoices} from 'forms/utils'
import RefundFormContent from './RefundFormContent'


const RefundForm = (
    {values=null, types, providers, onClose, showCross=false}
) => {

const fields = {
    type: {
        label: 'Type',
        choices: makeChoices(types),
        floatingLabel: true,
    },
    provider: {
        label: 'Demandeur',
        choices: makeChoices(providers),
        floatingLabel: true,
    },
    amount: {
        label: 'Montant',
        validators: [validateCurrency],
        floatingLabel: true,
        placeholder: 'euros',
    },
    comment: {
        label: 'Commentaire',
        required: false,
        floatingLabel: true,
    },
}
return (
    <Grid style={{backgroundColor: '#EEE', boxShadow: '1px 1px 5px 0 #A9A', 
     margin: '20px 0'}}>
        <Form
            component={RefundFormContent}
            componentProps={{onClose}}
            fields={fields}
            showCross={false}
        />
    </Grid>
  )
}

export default RefundForm

控制台没有错误,只是没有按预期显示。 通过 React 开发者工具我可以看到 props 和预期一样为 false,但显示不符合显示条件(即:'display nothing')。 最重要的是故事书,但我不确定这与显示问题有关:

import React from 'react'
import { storiesOf } from '@storybook/react'
import RefundAssignment from '../account/RefundAssignment'

storiesOf('RefundAssignment', module)
    .add('Affectation', () =>
        <RefundAssignment
            types={['1', '2', '3']}
            providers={['Deborah', 'Patrick', 'Severine', 
'Patrick Swayze']}
            showCross={false}
        />
    )

【问题讨论】:

  • 尝试将CrossButton函数移出RefundFormContent
  • 这确实是一个不错的举动,我没有尝试过。但问题还是一样。

标签: javascript reactjs ternary-operator react-props storybook


【解决方案1】:
  1. CrossButton 函数移出RefundFormContent 组件
  2. 也很高兴看到RefundFormContent(最好有 jsbin 演示)
  3. 您在RefundFormContent 的渲染中使用showCross&lt;CrossButton showCross /&gt;,但它不是通过道具定义的:const { fields, onClose, showCross } = this.props

【讨论】:

  • 1- 我将功能移出组件,但错误仍然相同。 2- 实际上,最上面的第一个组件是 RefundFormContent。但如果你更喜欢 jsbin,我会做一个。 3-我在道具中添加了 showCross 但它告诉我“showCross 已分配给一个值但从未使用过”,除非我放
【解决方案2】:

RefundFormContent 中,您没有传递showCross,而只是告诉元素始终为“showCrossed”..

&lt;input type="checkbox" checked /&gt;

你会像这样使用它:

<CrossButton showCross={this.props.showCross} />

【讨论】:

    【解决方案3】:
    import PropTypes from 'prop-types'
    import React from 'react'
    import {Cell} from 'react-mdl/lib/Grid'
    
    const CrossButton = (props) => {
            return <div>{props.visible ? <button
                  className="mdl-button mdl-js-button mdl-button--icon"
                  onClick={props.onClick}>x</button> : null}</div>
        }
    
    
    class RefundFormContent extends React.Component {
      render() {
        let fields = this.props.fields;
        let style = {width: '150px'};
    
        return (
            <React.Fragment>
                <Cell col={3}>
                    <Formfield {...fields.type} style={style} />
                </Cell>
                <Cell col={4}>
                    <Formfield {...fields.provider} style={style} />
                </Cell>
                <Cell col={4}>
                    <Formfield {...fields.amount} style={style} />
                </Cell>
                <Cell col={1} className="mdl-typography--text-right">
                    <CrossButton visible={this.props.showCross} onClick={this.props.onClose}/>
                </Cell>
            </React.Fragment>
        )
      }
    }
    
    export default RefundFormContent
    

    或者,如果应该使用短路显示,您只能调用 CrossButton,因此在上面的代码中,对 CrossButton 的更改将是:

    const CrossButton = (props) => {
            return <div><button
                  className="mdl-button mdl-js-button mdl-button--icon"
                  onClick={props.onClose}
              >x</button></div>
        }
    

    RefundFormContent 中的render 中,您将使用:

    //...
    <Cell col={1} className="mdl-typography--text-right">
                {this.props.showCross && <CrossButton onClick={this.props.onClose}/>}
            </Cell>
    //...
    

    编辑:

    要验证RefundFormContent 是否有效,只需将其渲染为:

    <RefundFormContent fields={fields} showCross={true} onClose={onClose}/>
    

    注意上面fieldsonClose必须是你要使用的props。

    上面的问题是,在 OP 中调用 RefundFormContent 是正确的方法吗?:

    <Form component={RefundFormContent}
                componentProps={{onClose}}
                fields={fields}
                showCross={false}
            />
    

    这里有多种道具,如果 Form 将上述正确传递给 RefundFormContent,那么它应该一切正常。

    【讨论】:

    • 这在代码方面非常有趣,但在这两种情况下都不会显示十字,(换句话说,恰恰相反)。
    • 已编辑,请独立测试RefundFormContent。
    • 还是一样:RefundFormContent 的组件中一切正常,也就是说,当有 showcross 道具时,会显示十字,当没有道具时,不会显示十字。问题出在 RefundForm 上,如果 showCross={false} 同时 showCross 在父级中为真,则为真并且与父级显示相同。
    【解决方案4】:

    感谢您的回答,我找到了问题所在:

    • 三元组起作用了
    • 道具很好地通过了组件

    --> 问题是在每个组件中定义一个 defaultProps 以清楚地说明预期的行为。 (我认为调用或不调用 showCross 会告诉我是否要显示十字架,但不是)。 所以你可以使用类似的东西:

    static defaultProps = {
        showCross: false,
    }
    

    或:

    const {showCross=false} = this.props;
    

    并在返回中

    <RefundCheckbox
       types={types}
       providers={providers}
       showCross={showCross}
    />
    

    如果 showCross = false 则不会显示十字,如果 showCross = true 则会显示。

    【讨论】:

      猜你喜欢
      • 2020-12-24
      • 1970-01-01
      • 2017-06-02
      • 1970-01-01
      • 2021-09-01
      • 2021-12-04
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      相关资源
      最近更新 更多