R9102
R9102

Reputation: 727

Unable to get values form child to parent -Reactjs Redux

I'm trying to update few values from child component to parent component. but not all data are getting updated.

Let me know if there is any error......

Can anyone help me on this?

Parent component

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

Child Component

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',
 };

Need to update

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

Need to pass all the above 4 values to parent (BOARD component). I am not able to update these above values. Can anyone help me on these? Please

Upvotes: 0

Views: 44

Answers (1)

Denys Kotsur
Denys Kotsur

Reputation: 2599

You should keep these values in the parent component and pass them as props to child. Also, you need to pass function callback to child (updater).

The idea is:

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`

}

Or just pass all of these values to your handleSaveButton callback.

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

Upvotes: 1

Related Questions