我正在尝试解决使用共享组件时遇到的问题。我的父组件看起来像这样..
index.js
import AuditData from './components/audit-data'
import StoredData from './components/stored-data'
class Audits extends PureComponent {
render = () => {
const {metroAudit} = this.props
const isMonthly = metroAudit.get('isMonthly')
return (
<Card className='animated fadeIn'>
<CardBody>
<Row>
<Col>
<h5 className='text-center'>Stored Data</h5>
<Card>
<CardBody><StoredData /></CardBody>
</Card>
</Col>
<Col>
<h5 className='text-center'>Audit Data</h5>
<Card>
<CardBody><AuditData /></CardBody>
</Card>
</Col>
</Row>
</div>}
</CardBody>
</Card>
)
}
}
除了他们使用的数据外,StoredData和AuditData是相同的。这两个组件都是这样的..
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import Immutable from 'immutable'
import cloneDeep from 'lodash/cloneDeep'
import { Row, Col } from 'reactstrap'
import { connect } from 'react-redux'
import Amenities from '../common/amenities'
import OwnershipType from '../common/ownership-type'
const initState = {
noAmenities: false,
feeSimple: true,
checkboxes: [{
label: '',
value: '',
checked: false
}]
}
class StoredData extends PureComponent {
static propTypes = {
series: PropTypes.instanceOf(Immutable.Map),
markets: PropTypes.instanceOf(Immutable.Map),
sbd: PropTypes.instanceOf(Immutable.Map)
}
constructor (props) {
super(props)
this.state = initState
}
componentDidUpdate = prevProps => {
const { markets } = this.props
const prevMarket = prevProps.markets.get('market')
const market = markets.get('market')
if (market !== prevMarket) this.setState(initState)
}
componentDidMount = () => {
this._setData()
}
_setData = () => {
const { sbd } = this.props
const _checkboxes = sbd.get('amenities').toJS()
const _amenities = sbd.getIn(['data', 'amenities']).toJS()
_checkboxes.shift()
_checkboxes.forEach(x => {
x.isDisabled = true
x.checked = !!_amenities.find(y => y.value === x.value)
})
this.setState({checkboxes: _checkboxes})
}
_onOwnershipType = e => {
const val = e.target.value
const _state = cloneDeep(this.state)
_state.feeSimple = val !== 'condoOwnership'
this.setState(_state)
}
_onNoAmenities = () => {
const { checkboxes } = this.state
const _checkboxes = cloneDeep(checkboxes)
_checkboxes.forEach(x => {
x.checked = false
})
this.setState({ noAmenities: !this.state.noAmenities, checkboxes: _checkboxes })
}
_onAmenities = (e, i) => {
const { checkboxes } = this.state
const _checkboxes = cloneDeep(checkboxes)
_checkboxes[i].checked = !_checkboxes[i].checked
this.setState({checkboxes: _checkboxes})
}
render = () => {
return (
<div>
<Row>
<Col>
<OwnershipType
isStoredData
onOwnershipType={this._onOwnershipType}
{...this.state}
/>
</Col>
</Row>
<Row>
<Col>
<Amenities
onNoAmenities={this._onNoAmenities}
onCheckboxes={this._onAmenities}
{...this.state}
/>
</Col>
</Row>
</div>
)
}
}
const mapStateToProps = state => ({
series: state.series,
markets: state.markets,
sbd: state.sbd
})
export default connect(mapStateToProps)(StoredData)
这两个组件也是共享的。
import Amenities from '../common/amenities'
import OwnershipType from '../common/ownership-type'
ownershipType.js
import React, {PureComponent} from 'react'
import PropTypes from 'prop-types'
import { CardBody, Card, Row, Col } from 'reactstrap'
import CardTitle from '../../../../../../../components/CardTitle'
import Radios from '../../../../../../../components/Radios/index'
export default class OwnershipType extends PureComponent {
static propTypes = {
feeSimple: PropTypes.bool,
isStoredData: PropTypes.bool,
onOwnershipType: PropTypes.func
}
render = () => {
const {feeSimple, isStoredData, onOwnershipType} = this.props
return (
<Card className='animated fadeIn'>
<CardTitle
color='default'
h6Class='card-h6-sbd'
className='card-title-sbd'
title='Ownership Type' />
<CardBody>
<Row>
<Col>
<Radios
name={`${isStoredData ? 'ownershipType' : 'ownershipType-1'}`}
label1='Fee Simple'
label2='Condo Ownership'
value1={'feeSimple'}
value2={'condoOwnership'}
checked1={feeSimple}
checked2={!feeSimple}
onChange={onOwnershipType}
/>
</Col>
</Row>
</CardBody>
</Card>
)
}
}
amenities.js
import React, {PureComponent} from 'react'
import PropTypes from 'prop-types'
import uuid from 'uuid'
import { CardBody, Card, Row, Col } from 'reactstrap'
import CardTitle from '../../../../../../../components/CardTitle'
import Checkbox from '../../../../../../../components/Checkbox/index'
export default class Amenities extends PureComponent {
static propTypes = {
noAmenities: PropTypes.bool,
onNoAmenities: PropTypes.func,
onCheckboxes: PropTypes.func,
checkboxes: PropTypes.array
}
render = () => {
const {noAmenities, onNoAmenities, checkboxes, onCheckboxes} = this.props
return (
<Card className='animated fadeIn'>
<CardTitle
color='default'
h6Class='card-h6-sbd'
className='card-title-sbd'
title='Amenities' />
<CardBody>
<Row>
<Col>
<Checkbox
name='noAmenities'
value='noAmenities'
label='No Amenities'
divClass='pull-right'
checked={noAmenities}
onChange={onNoAmenities}
/>
</Col>
</Row>
<Row>
{checkboxes.map((item, i) => (
<Col key={i} sm={6} md={6} lg={6}>
<Checkbox
name={uuid.v4()}
disabled={item.isDisabled}
value={item.value}
label={item.label}
checked={item.checked}
onChange={e => onCheckboxes(e, i)}
/>
</Col>
))}
</Row>
</CardBody>
</Card>
)
}
}
问题是我设置数据的时候。当我同时“StoredData”和“AuditData”呈现时,StoredData复选框未正确设置。如果比较“_setData”函数,您将看到StoredData具有动态数据,用于确定是否选中了每个复选框。但是,两个组件都通过AuditData设置复选框 “_setData”函数。共享具有相同父组件的组件时是否存在参考问题?我之前没有遇到过这个问题,也不知道要搜索什么。
答案 0 :(得分:0)
import React, { PureComponent } from 'react'
import { Row, Col, Card, CardBody } from 'reactstrap'
import PropTypes from 'prop-types'
import ReactTimeout from 'react-timeout'
import AuditData from './components/audit-data'
import StoredData from './components/stored-data'
class MetroAuditMain extends PureComponent {
static propTypes = {
setTimeout: PropTypes.func
}
constructor (props) {
super(props)
this.state = {hidden: true}
}
componentWillMount = () => {
this.props.setTimeout(() => this.setState({hidden: false}), 500)
}
render = () => {
const {hidden} = this.state
return (
<Row className='animated fadeIn'>
<Col xs={12} sm={12} md={12} lg={6} xl={6}>
<Card>
<CardBody>
<StoredData />
</CardBody>
</Card>
</Col>
<Col xs={12} sm={12} md={12} lg={6} xl={6}>
<Card>
<CardBody>
{!hidden && (
<AuditData />
)}
</CardBody>
</Card>
</Col>
</Row>
)
}
}
export default ReactTimeout(MetroAuditMain)
我通过延迟第二个组件的渲染来解决了这个问题。我不明白为什么有必要这样做,如果有人可以评论这将有所帮助。感谢