Liam
Liam

Reputation: 6743

ReactJS & Redux access state "constructor" from another file

I'm just trying to post a data everything working fine if I put the fetch function in the same file but when I moved it to another file it shows cannot read property, I've tried this.props instead of this.state, how can I connect this file to constructor()

enter image description here

scr/component/layout.js

import React, {Component} from 'react';
import { connect } from 'react-redux';
import {bindActionCreators} from 'redux'; 
import { fetchUsers, postUsers } from '../actions/usersAction';


class Layout extends Component {
constructor(){
    super() 
    this.state = {  
        name: '',
        age: ''}
}

onUserUpdate(filed, event){
    console.log('onUserUpdate: ' + filed + '==' + event.target.value);
    if (filed == 'name') {
        this.setState({
            name: event.target.value
        })
        return
    }
    if (filed == 'age') {
        this.setState({
            age: event.target.value
        })
        return
    }
}


componentDidMount() {  
  this.props.fetchUsers();
}
  render() {

    const { act } = this.props;

      const fetchUserss = act.users.map(d =>  <tr key={d.id}><td>{d.name}</td><td>{d.age}</td></tr>);

    return (
      <div className="App">
        <label>
            name:
              </label>
            <input type="text" name="name" onChange={this.onUserUpdate.bind(this, 'name')} placeholder="Enter Name"/>
                <label>
                age:
              </label>
                <input type="text" name="age" onChange={this.onUserUpdate.bind(this, 'age')} placeholder="enter username"/>
                <button type="simpleQuery" onClick={this.props.postUsers.bind(this)}>Add News</button>
    
            <table>
                <thead>
                <tr>
                      <th>Name</th>
                </tr>
                </thead>
                <tbody>
                 {fetchUserss}
                </tbody>
            </table>
        </div>
    );
  }
}



function mapStateToProps(state) {
    return {
        act: state.users,
    };
}

function matchDispatchToProps(dispatch) {
    return bindActionCreators({fetchUsers, postUsers}, dispatch)
}
export default connect(mapStateToProps, matchDispatchToProps)(Layout);

src/actions/userAction.js

export const fetchUsers = (data) =>{
            return{
            type: "USERS",
            payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                }
                
            })
            .then(res => res.json())
    }
};
export const postUsers = (event) =>{
    let users = {
        name: this.state.name,
        age: this.state.age
    }
    return{
            type: "USERS_POST",
            payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(users),
            })
            .then(res => res.json())
    }
};

src/reducers/userReducer.js

const initalState = {
fetching: false,
fetched: false,
users: [],
error: null
};
export default function(state=initalState, action) {
    let newState = Object.assign({}, state);
    switch(action.type){
        case "USERS_PENDING":{
            return {...state, fetching: true,loading: false,}
        }
        case "USERS_FULFILLED":{
            return {...state, fetching:false, fetched: true, users: action.payload,}
        }
        case "USERS_REJECTED":{
            return {...state, fetching: false, error: action.payload,}
        }
        case "USERS_POST_PENDING":{
            return {...state, fetching: true,}
        }
        case "USERS_POST_FULFILLED":{
              return newState;
        }
        case "USERS_POST_REJECTED":{
            return {...state, fetching: false, error: action.payload,}
        }
        default:
            return state;
    }
}

Please let me know if I miss out any information.

If this has already been asked, I would greatly appreciate if you are able to point me in the right direction.

Thank you so much!

Upvotes: 0

Views: 610

Answers (3)

l0gicgate
l0gicgate

Reputation: 183

You need to pass that data to your postUsers() function.

<button 
  type="simpleQuery" 
  onClick={() => this.props.postUsers(this.state.name,this.state.age)}
>Add News</button>

Then in your postUsers() function should take in those parameters:

export const postUsers = (name, age) => ({
  type: "USERS_POST",
  payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name,
      age,
    }),
  })
    .then(res => res.json())
});

Upvotes: 2

Pubudu Dodangoda
Pubudu Dodangoda

Reputation: 2874

I can see that you have tried to bind a scope to an arrow function. You cannot do that. Arrow functions do not have a scope.

Instead, you should write a normal function.

either,

let postUsers = function() {};

or

function postUsers(){}

In other words this inside an arrow function is always inherited from the parent function. So in your case, this is not undefined, but it is not the this you expect.

Upvotes: 1

GZedd
GZedd

Reputation: 53

We cannot access state outside of a component. You can pass the state variables are params to the postUsers function.

<button type="simpleQuery" onClick={this.props.postUsers(this.state.name,this.state.age)}>Add News</button>

And in your postUsers function

export const postUsers = (name,age) =>{
let users = {
    name: name,
    age: age
}
return{
        type: "USERS_POST",
        payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(users),
        })
        .then(res => res.json())
}

};

Upvotes: 2

Related Questions