根据条件渲染后调用的道具,React不会更改渲染

时间:2018-03-26 09:37:56

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

我有一个带有条件渲染的组件:'如果组件有prop“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开发人员工具,我可以看到道具是按预期的假,但显示不符合显示条件(也就是说:'什么都不显示')。 最重要的是故事书,但我不确定这是否与显示问题有关:

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}
        />
    )

4 个答案:

答案 0 :(得分:0)

  1. CrossButton功能移出RefundFormContent组件
  2. 很高兴看到RefundFormContent(jsbin演示会是最好的)
  3. 您在showCross的渲染中使用RefundFormContent<CrossButton showCross />但未通过道具定义:const { fields, onClose, showCross } = this.props

答案 1 :(得分:0)

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> } 的更改将是:

render

并在RefundFormContent //... <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}/> 是否有效,请将其渲染为:

fields

请注意,上面onCloseRefundFormContent必须是您要使用的道具。

上面的问题是,正在OP中调用<Form component={RefundFormContent} componentProps={{onClose}} fields={fields} showCross={false} /> ,正确的方法吗?:

input[type=password]

这里有各种道具,如果Form正确地将上述内容传递给RefundFormContent,那么它应该都能正常工作。

答案 2 :(得分:0)

RefundFormContent中你没有传递showCross,只是告诉元素永远是&#34; showCrossed&#34; ..

<input type="checkbox" checked />相同。

您将使用它:

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

答案 3 :(得分:0)

我发现问题归功于你的答案让我走上了正轨:

  • 三元工作
  • 道具通过组件

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

static defaultProps = {
    showCross: false,
}

或:

const {showCross=false} = this.props;

并在回报中

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

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