javascript - ReactJS - 子组件在使用导入组件时不会渲染,但在父元素中显式标记时会渲染

标签 javascript reactjs

我正在为 freeCodeCamp.org 项目构建一个投票应用程序。

每个民意调查都有一个投票选项列表。

在一次民意调查中,我试图呈现所有可用的选项进行投票。

直接在投票组件中标记投票选项是可行的,但当我将标记分解到“选项”子组件时则不起作用。

在react dev-tools中,出现了一个connect标签,但没有DIV,这让我认为我处理渲染的方式都是错误的。

图像 Child component does not render (via React Dev Tools)

a_poll.js(父组件)

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PollOption from './poll_option';
import  * as Actions from '../actions';

class APoll extends Component {

componentDidMount() {
    this.props.fetchAPoll(this.props.params.postId);
}  

renderOption(pollData) {
    //console.log("renderOption:", pollData.options);
    return (
           pollData.options.forEach(function(option) {
              return (
                <PollOption title={option.title} value={option.value} />
              ); 
           })
        );
}

render() {
    const a_poll = this.props.a_poll ? this.props.a_poll : "nothing here";
    return (
        <div>
            <div>{ a_poll.title } : {a_poll.user_name}</div>
            <div>{a_poll.map(this.renderOption)}</div>
        </div>
    );
}

};

function mapStateToProps({a_poll}) {
return { 
    a_poll
};
}

export default connect(mapStateToProps, Actions)(aPoll);

PollOption.js(子组件)

import { connect } from 'react-redux';
import  * as Actions from '../actions';

function PollOption(props) {

return (
    <div key={ this.props.title }  style={{ clear: 'left' }}>
            <h6>{ this.props.title }hgjgjg : </h6>
            <div style={{marginTop : "5px"}}>
                <div style={{ 
                        display: "inline-black",
                        float: "left",
                        backgroundColor : "cornflowerblue",
                        height : "50",
                        padding : "15",
                        marginBottom : "15px",
                        minWidth: "50px",
                        width : option.value,
                        color: "white",
                        lineHeight: "25px"
                    }}>
                    <div style={{ 
                        display : "inline-block",
                    }}>
                        { this.props.value }
                    </div>
                </div> 
                <button 
                    style={{ 
                    display: "inline-block",
                    height: "50",
                    marginLeft: "20",
                    }} 
                    className="btn btn-primary"
                    onClick={console.log("vote buttoned clicked")}
                    > 
                    Vote 
                </button>
            </div>
        </div>
);
} 

export default connect(Actions)(PollOption);

最佳答案

我将用简单的语法来标记它并跳过大部分代码。问题是您实际上并没有更新内容,因此当状态发生变化时,没有任何内容可以更新。

这是一个您可以测试的简单组件,它可能会解释您的问题:

//测试.js

import React from 'react'

let counter = 0
class TestPage extends React.Component {
  constructor() {
    super()
    this.state = {
      data: []
    }
  }

  componentDidMount() {
    this.setState({
      data: [
        'a','b','c'
      ]
    })
  }

  badAddToState() {
    this.state.data.push(('bad' + counter++))
  }

  addToState() {
    let copy = this.state.data.slice() //make a new array
    copy.push('good' + counter++)
    let newState = Object.assign({}, this.state, {
      data: copy
    })
    this.setState(newState)
  }
  render() {
    const { data } = this.state || { data: [] } //ES6 destructuring syntax
     return (
       <div>
         <button
           onClick = { (e) => { 
             this.badAddToState()
             console.log('bad clicked')
             console.log('counter->' + counter)
           } }
         >
           BAD
         </button>
         <button
         onClick = { (e) => { 
             this.addToState()
             console.log('good clicked')
             console.log('counter->' + counter)
           } }
         >
           GOOD
         </button>
         <h1>Good data</h1>
         { this.state.data.map( (x) => {
           return (<div key={x}>Hi I'm {x}</div>) //this is effectively your child
         })}
       </div>

     )
  }
}
export default TestPage

所以这是怎么回事?基本上,“BAD”按钮正在更新您的状态,但不会告诉组件它已经修改了状态。 “GOOD”按钮使用 setState 方法将数据推送回组件,表示“嘿,我需要更新”(您可以看到它实际上产生了结果,但组件没有更新。)

enter image description here

那么我为什么给你这个例子来玩呢?我认为您没有看到 Redux 在基础层面上是如何工作的。 Redux(连接)正在获取全局状态并将其映射到 {component}.props 在您的情况下,您只需将操作映射到属性(您不需要做的事情,但是可以做)。

当您从安装中获取项目时(就像我刚刚推送了一个数组),您需要对其进行一些操作。在典型的 Redux 模式中,这意味着您要反射(reflect)全局状态。

因为您的组件似乎并不依赖于您的结果,所以没有理由重新绘制它?

您想要确保您正在获取的“民意调查”已被映射。如果 parent 已经知道某件事,那么让 child 实例化一个 Action 来检索某些东西是否有意义?

简化一下:

//...boilerplate child | It isn't connected to redux
render() {
  return(
    <Markup>
      { this.props.poll.name }
      <button 
        onClick={e=>{
          //This changes the global state **1**
          dispatch(doSomethingEvent()) //confession I use Thunk because I like more actions
        }}>
          Do Something
        </button>
    </Markup>
  )
}

//...boilerplate paernt
render() {
  //**2** WHICH IS RENDERED HERE WHEN IT CHANGES
  const { dispatch, polls } = this.props
  return (
    <div>
      { polls.map( (poll, index)=>{
        return <Poll pollObject={poll} key={index || poll.uuid } dispatch={dispatch} />
      } ) }
    </div>
  )
}     

///...mapping
connect(state => {
  polls = state.whereEverYouStorePolls
})(Parent)

1) 该操作改变了状态——您没有发布代码,但它是“业务逻辑” 2) 更改反射(reflect)在父级中,并传播到子级。

这有帮助吗?

简短的回答是,您正在显示组件,但从不调用渲染,因为您希望轮询能够反射(reflect)获取操作的状态而不依赖于它。翻转数据结构——渲染不应该要求数据,而应该提供数据。

关于javascript - ReactJS - 子组件在使用导入组件时不会渲染,但在父元素中显式标记时会渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46291069/

相关文章:

Django、React、Redux : Serving up images

html - 在 React 中 dangerouslySetInnerHTML 不适用于 html 标签。

javascript - AngularJS - 如何创建具有特定格式的表单?

javascript - 如何使用 JavaScript 检索文档集的元数据

php - 验证文本框输入以逗号分隔的 3 位数字

javascript - react 中的延迟加载 - 组件未加载

javascript - 如果选择了另一个选项,如何取消选择来自 Array 的选项

javascript - React-bootstrap 选项卡 : Warning: In the context of a `<TabContainer>` , `<NavItem>` s 被赋予生成的 `id` 和 `aria-controls` 属性

javascript - jQuery 在更改时获取选定的下拉值

javascript - 如何在 react-bootstrap 中获取选择元素的值?