0

I am new to redux with intermediate experience in React. I have two components ButtonAppBar and CriticalIssues. I am trying to reveal the CriticalIssues component on click of a button in ButtonAppBar. ButtonAppBar is throwing Cannot read property 'props' of undefined when the button is clicked. I have been stuck on this for a long time, any help would be appreciated.

My code is:

ButtonAppBar.js

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import styled from 'styled-components'
import CriticalIssues from '../CriticalIssues'

import { showCriticalBugs } from 'containers/App/actions';
import { connect } from 'react-redux';
import { show_critical } from '../../containers/App/sagas';

const styles = {
    root: {
        flexGrow: 1,
    },
    grow: {
        flexGrow: 1,
        textAlign: "left"
    },
    menuButton: {
        marginLeft: -12,
        marginRight: 20,
    },
};

const Button = styled.button`
background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
border-radius: 3px;
border: 0;
color: white;
height: 48px;
padding: 0 30px;
box-shadow: 0 3px 5px 2px rgba(255, 105, 135, .3);
`

export class ButtonAppBar extends React.Component {
    
    constructor(props) {
        super(props);
    }

    componentDidMount(){
        this.showCritical();
    }

    showCritical(){
        this.props.dispatch(showCriticalBugs());
    }

    render() {
        return (
            <div>
                <AppBar position="static">
                    <Toolbar>

                        <Typography variant="h6" color="inherit">
                            Regression 360
                         </Typography>
                        <Button onClick={this.showCritical} color="inherit">Predict Critical Bugs</Button>
                    </Toolbar>
                </AppBar>
            </div>
        );
    };
}
ButtonAppBar.propTypes = {
    dispatch: PropTypes.func,
  };

export default connect()(ButtonAppBar);

sagas.js

import {showCriticalBugs} from './actions'
import { call, cancel, select, take, takeLatest, put } from 'redux-saga/effects';

export function* show_critical (){
    yield put(showCriticalBugs());
}

actions.js

export const SHOW_CRITICAL = 'SHOW_CRITICAL';

export function showCriticalBugs() {
    return {
      type: SHOW_CRITICAL,
    };
  }

reducer.js

import SHOW_CRITICAL from './actions'

const initialState = fromJS({
    visible: false
  });
  

  function appReducer(state = initialState, action) {
    switch (action.type) {
      case SHOW_CRITICAL:
        console.log("m here");
        return state.set('visible', true);
    }
}
    

export default appReducer;

CriticalIssue.js

import React from 'react';
import PropTypes from 'prop-types'
import { connect } from 'react-redux';
import { Card, Typography, Button } from '@material-ui/core'


var mainDiv = {
  padding: 10,
  width: "auto",
  fontFamily: "monospace",
  textAlign: "center"
};


class CriticalIssues extends React.Component {
  componentDidMount(){
    console.log(this.props.visible)
  }
  render() {
    if (this.props.visible) {
      return (
        <Card>
          <div style={mainDiv}>
            <Typography variant={'h1'} color={"error"}>3</Typography>
            <Typography component={"h3"}>Critical Issues</Typography>
          </div>
        </Card>
      );
    }
    else return (null);
  }
}

function mapStateToProps(state) {
  return {
    visible: state.getIn(['global', 'visible']),
  };
}

export default connect(mapStateToProps)(CriticalIssues);
Arshak Anj
  • 149
  • 1
  • 2
  • 8
  • Search for "JavaScript this undefined" and you'll get no end of hits. – jonrsharpe Dec 20 '18 at 11:16
  • Your props is not being passed into the component in the first place. – Jonast92 Dec 20 '18 at 11:17
  • Possible duplicate of [Why do I have to .bind(this) for methods defined in React component class, but not in regular ES6 class](https://stackoverflow.com/questions/39552536/why-do-i-have-to-bindthis-for-methods-defined-in-react-component-class-but-n) – Fabio Antunes Dec 20 '18 at 11:18

1 Answers1

0

You must bind your function to access 'this' keyword in your method you can use this

<Button onClick={this.showCritical.bind(this)} color="inherit">Predict Critical Bugs</Button>

or you can also bind your methods in constructor like below

constructor(props){
  super(props)
  this.showCritical = this.showCritical.bind(this)
}
Fabio Antunes
  • 22,251
  • 15
  • 81
  • 96
Vikas Verma
  • 84
  • 1
  • 6