无法从子级到父级-Reactjs Redux获取值

时间:2018-05-27 18:14:31

标签: reactjs redux

我正在尝试将少量值从子组件更新到父组件。 但并非所有数据都在更新。

如果有任何错误,请告诉我......

有人可以帮我吗?

父组件

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      invalidData: {},
      widgetsList: [],
      storyboardList: [],
      storyboardTitle: this.props.selectedBoard.boardTitle,
      isHidden: true,
      widgetCount: 0
    };
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.storyboardList !== nextProps.storyboardList) {
      this.setState({ storyboardList: nextProps.storyboardList });
    }
  }

  addWidget = widgetType => {
    const newWidget = this.getNewWidget(widgetType);
    this.setState(
      {
        widgetsList: [...this.state.widgetsList, newWidget],
        isHidden: !this.state.isHidden,
        widgetCount: this.state.widgetCount + 1
      },
      () =>
        this.props.storyboardActions.addWidget(
          newWidget,
          this.props.selectedBoard.boardId
        )
    );
  };
  getNewWidget = widgetType => {
    if (this.props.storyboardList.length === 0) {
      console.log("stb", this.state.storyboardList.widgetList);
    }
    switch (widgetType) {
      case "venn":
        return {
          widgetName: `widget ${this.state.widgetCount}`,
          widgetType: "venn",
          leftTarget: "",
          rightTarget: "",
          leftTargetValue: 0,
          rightTargetValue: 0,
          position: { row: 0, col: 0 }
        };
      default:
        return {
          widgetName: `Default ${this.state.widgetCount}`,
          widgetType: "venn",
          leftTarget: "",
          rightTarget: ""
        };
    }
  };

  handleSaveButton = selectedBoardId => {
    const expressionsToSaveWidget = { ...this.getUserAccountRunParams() };
    console.log(this.props.storyboardList.boardList[selectedBoardId].spcxId);
    console.log(this.props.storyboardList.boardList[selectedBoardId]);
    this.props.storyboardList.boardList[selectedBoardId].spcxId === ""
      ? this.props.storyboardActions.newStoryboard(
          expressionsToSaveWidget,
          this.state.storyboardTitle,
          this.props.storyboardList.boardList[selectedBoardId]
        )
      : this.props.storyboardActions.updateStoryBoard(
          expressionsToSaveWidget,
          this.state.storyboardTitle,
          this.props.storyboardList.boardList[selectedBoardId]
        );
  };

  render() {
    return (
      <VennDiagram
        boardId={this.props.selectedBoard.boardId}
        widgetDetail={widget}
        storyboardTargets={this.props.storyboardTargets}
        handleSaveButton={this.handleSaveButton}
        //handleWidgetChange={this.handleWidgetChange}
        handleRunWidget={this.handleRunWidget}
        handleDeleteWidget={this.handleDeleteWidget}
        handleDuplicateWidget={this.handleDuplicateWidget}
        handlechangeTarget={this.handlechangeTarget}
      />
    );
  }
}

子组件

class VennDiagram extends React.Component {
constructor(props) {
super(props);
this.state = {
  currentDropdown: '',
  leftValue: 'A',
  rightValue: 'B',
  interSectionData: 'AB',
  };
  }
handelSelectionChange = baseData => {
  const Venndata = baseData.weighted;
  const venntext = baseData.keyword;
  console.log("widgetDetail", this.props.widgetDetail);
  let updatedWidget = {};
  const interSec =
    this.state.leftValue === "A" || this.state.leftValue === "B"
      ? "AB"
      : baseData.sample;
  if (this.state.currentDropdown === "left") {
    updatedWidget = {
      leftTarget: venntext,
      leftTargetValue: Venndata,
      widgetId: this.props.widgetDetail.widgetId,
      widgetName: this.props.widgetDetail.widgetName,
      widgetType: this.props.widgetDetail.widgetType
    };
    this.setState({
      leftValue: Venndata,
      interSectionData: interSec,
      lefttext: venntext
    });
    // this.props.handleWidgetChange(Venndata, 'left');
  } else {
    updatedWidget = {
      rightTarget: venntext,
      rightTargetValue: Venndata,
      widgetId: this.props.widgetDetail.widgetId,
      widgetName: this.props.widgetDetail.widgetName,
      widgetType: this.props.widgetDetail.widgetType
    };
    this.setState({
      rightValue: Venndata,
      interSectionData: interSec,
      righttext: venntext
    });
  }
  this.props.handleSaveButton(this.props.boardId);
  this.handleDropDownClose();
};
render() {
return (
  <div className="widget-wrapper">
    {this.props.storyboardTargets ? (
      <div className="target-base-dropdown" ref={node => (this.targetBaseDropdown = node)}>
        <h6>
          Select Target
          <button className="dropdown-close-button" onClick={this.handleDropDownClose}>
            <img src={clearIcon} alt="Close button" title="Close" />
          </button>
        </h6>
        <ul>
          {this.props.storyboardTargets &&
            this.props.storyboardTargets.map((base, index) => (
              <li key={index} value={base.keyword} onClick={() => this.handelSelectionChange(base)}>
                {base.originalTitle}
              </li>
            ))}
        </ul>
      </div>
    ) : (
      ''
    )}
    <svg
      xmlns="http://www.w3.org/2000/svg"
      version="1.1"
      xmlnsXlink="http://www.w3.org/1999/xlink"
      width={415}
      height={240}
      style={{ fontSize: '15px' }}
    >
      <ellipse
        cx="150"
        cy="125"
        rx="100"
        ry="100"
        fill={this.state.leftValue === 'A' ? 'rgba(93, 86, 90, 0.3)' : this.props.leftBGColor}
        style={{ stroke: '#204454', strokeOpacity: '0.5' }}
      />
      <ellipse
        cx="275"
        cy="125"
        rx="100"
        ry="100"
        fill={this.state.rightValue === 'B' ? 'rgba(93, 86, 90, 0.3)' : this.props.rightBGColor}
        style={{ stroke: '#724f65', strokeOpacity: '0.5' }}
      />
      <text y="125" textAnchor="middle" id="1:77%">
        <tspan x="77%" dy="0" onClick={e => this.showDropdown(e, 'right')} className="right-value">
          {this.state.righttext} {this.state.rightValue}
        </tspan>
      </text>
      <text y="125" textAnchor="middle" id="2:23%">
        <tspan x="23%" dy="0" onClick={e => this.showDropdown(e, 'left')} className="left-value">
          {this.state.lefttext} {this.state.leftValue}
        </tspan>
      </text>
      <text y="125" textAnchor="middle" id="12:50%">
        <tspan x="50%" dy="0">
          {this.state.interSectionData}
        </tspan>
      </text>
    </svg>
    <p contentEditable="true" className="text-center">
      {this.props.widgetDetail.widgetName}
    </p>
    <Modal title="Add Target/Targets" ref={node => (this.addtarget = node)} dialogStyles={ModalAddTargetStyle}>
      <p>Please add target/targets to select.</p>
    </Modal>
  </div>
  );
  }
  }

 VennDiagram.defaultProps = {
 leftValue: 'A',
 leftBGColor: 'rgba(64, 137, 169, 0.3)',
 rightValue: 'B',
 rightBGColor: 'rgba(229, 159, 202, 0.3)',
 middleValue: '',
 widgetName: 'Widget 1',
 };

需要更新

    rightTarget: venntext,
    rightTargetValue: Venndata,
    leftTarget: venntext,
    leftTargetValue: Venndata,

需要将以上所有4个值传递给父级(BOARD组件)。 我无法更新上述值。有人可以帮我这些吗?请

1 个答案:

答案 0 :(得分:1)

您应该将这些值保留在父组件中,并将它们作为道具传递给子组件。此外,您需要将函数回调传递给child(更新程序)。

这个想法是:

<强> Board.js

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rightTarget: '',
      rightTargetValue: '',
      leftTarget: '',
      leftTargetValue: '',
      // another part of state
    };
  }

  onValuesChange = values => {
      this.setState({ ...values })
  }

  render() {
      const { rightTarget, rightTargetValue, leftTarget, leftTargetValue } = this.state
      return (
          <VennDiagram 
                onValuesChange={this.onValuesChange}
                rightTarget={rightTarget}
                rightTargetValue={rightTargetValue}
                leftTarget={leftTarget}
                leftTarget={leftTargetValue}
          />
      )
  }
}

<强> VennDiagram.js

class VennDiagram extends React.Component {
     ... all component's code above

     handelSelectionChange = baseData => {
          ... rest code 

          this.props.onValuesChange({ rightTarget: venntext,
                                      rightTargetValue: Venndata,
                                      leftTarget: venntext,
                                      leftTargetValue: Venndata, })
     }

     ... render etc
     // use all of these values (rightTarget, leftTarget, rightTargetValue, leftTargetValue) from `this.props` instead of `this.state`

}

或者只是将所有这些值传递给handleSaveButton回调。

// in child's component
this.props.handleSaveButton(this.props.boardId, { rightTarget: venntext,
                                          rightTargetValue: Venndata,
                                          leftTarget: venntext,
                                          leftTargetValue: Venndata, })

// in parent
handleSaveButton = (selectedBoardId, values) => {
    ... rest of the code
    this.setState({...values})
}