0

I'm learning React from past two weeks.Currently I am taking course on Udemy of Stephen Grider. I am building a dummy streaming platform just like twitch where I can create,delete,edit and watch streams.

Right now I was writing the StreamDelete component which will show a modal where the user can either delete the particular stream or cancel.

Here is the code what I have written:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React from "react";
import Modal from "../modal";
import history from "../../history";
import { connect } from "react-redux";
import { fetchIndividualStream } from "../../actions";

class streamDelete extends React.Component {
  componentDidMount() {
    this.props.fetchIndividualStream(this.props.match.params.id);
  }

  action = () => {
    return (
      <React.Fragment>
        <button className="ui button negative">Delete</button>
        <button className="ui button">Cancel</button>
      </React.Fragment>
    );
  };

  renderContent = () => {
    return `Are you sure you want to delete : ${
      this.props.streams
        ? this.props.streams[this.props.match.params.id].title
        : ""
    }`;
  };

  render() {
    return (
      <Modal
        title="Delete Stream"
        content={this.renderContent()}
        action={this.action()}
        onDismiss={() => history.push("/")}
      />
    );
  }
}

const mapStateToProps = (state) => {
  return { stream: state.streams };
};

export default connect(mapStateToProps, {
  fetchIndividualStream,
})(streamDelete);

Here fetchIndividualStream action will fetch the stream which is to be deleted from the API and store it in the state. The redux store after this operation looks like this

state


Output I'm getting:

Output I'm getting

What should be the OUPUT:

This should be the output The modal will be present when the component first render with state as null as well as when the stream is successfully fetched.The only difference is after successful fetching the title will be displayed after "Are you sure you want to delete : ".See the renderContent method.

My problem is the modal is not displaying the title even after the state is updated just like the first image. I don't know the problem however on changing some code it worked.

The changes I made were in mapStateToProps and in the renderContent method.

mapStateToProps

const mapStateToProps = (state, ownProps) => {
   return { stream: state.streams[ownProps.match.params.id] };
 };

renderContent method:

renderContent = () => {
    return `Are you sure you want to delete : ${
       this.props.stream ? this.props.stream.title : ""
     }`;
   };

EDIT: Link to the Github repository

Yogesh Tripathi
  • 703
  • 5
  • 16

1 Answers1

0

You're seems to be using react-router-dom and want to get parameter from the url?

You need to use withRoute HOC to get access to .match / this.props.match.params.id. Please refer to example below.

Docs: https://reacttraining.com/react-router/core/api/withRouter connect(mapStateToProps, mapDispatchToProps)(withRouter(Dashboard))

import React from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";

// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  };

  render() {
    const { match, location, history } = this.props;

    return <div>You are now at {location.pathname}</div>;
  }
}

// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);

So in your particular case you need to do this.

export default connect(mapStateToProps, {
  fetchIndividualStream,
})(withRouter(streamDelete)); // withRouter higher order component.
MonteCristo
  • 1,471
  • 2
  • 20
  • 41
  • why I cannot directly access the this.props.match.params.id from the component. Also why my later modification worked ? – Yogesh Tripathi May 01 '20 at 13:31
  • What later modification? – MonteCristo May 01 '20 at 13:32
  • In the mapStateToProps function and renderContent method. I mentioned this in my question. – Yogesh Tripathi May 01 '20 at 13:34
  • it's hard for me to say without looking at the whole application. if you like you can put this on codesandbox.io so could take a deeper look. From code you've given you have this `this.props.stream.title` this is not the same as `this.props.streams[this.props.match.params.id].title`. You might be setting `streams.title` somewhere through some actions? but that's not coming from route params. – MonteCristo May 01 '20 at 13:38
  • `this.props` refers to properties that are passed from parent. e.g. `` I am sure you're not setting that in parent. You're not just going to get access to a property that's not passed down. `withRouter` higher order component sets that property. [more on this](https://stackoverflow.com/questions/53539314/what-is-withrouter-for-in-react-router-dom) – MonteCristo May 01 '20 at 13:42