0

Good morning,

I am converting an application over from props drilling to useContext and am encountering a strange issue. A function I have assigned to a prop is seen as a function as a drilled prop but not when pulled out of a created context. I have other functions in that same context that work just fine. Below you will find the portions of my components that are relevant to the question:

root component:

import UserContext from '../context/userContext';
/*...imports
*/

const wageTrak = (props) => {
const [userState, setUserState] = useState({});
const [jobState, setJobState] = useState({});

                                //this is usable as a function
const contextArr = [ userState, setUserState, 
                               //this is not
                     jobState, setJobState ];

/* ...more code
 *
 */

let userData = "Loading...";

if (userState) {
    userData = <User
        //I am trying to eliminate this but I can't seem to
        setJob={setJobState}
    />
}

return (
    <React.Fragment>
        <UserContext.Provider value={[...contextArr]}>
             ....
            <Route
                    path="/wagetrak/"
                    render={() => userData}
                />
             . . . 
        </UserContext.Provider>

User component:

import UserContext from '../../context/userContext';
//imports

const user = (props) => {
const [ showModal, setShowModal ] = useState({});
const [ userState ] = useContext(UserContext);

/*
 * functions
 */

return (
    <React.Fragment>
        <main className="user">
            <header className="margin flexDiv" onClick={() => clickedNameHandler()}>
                <div className="userName capitalize">{userState.name}</div>
                {window.location.pathname === "/wagetrak" && 
                    <div className="editDiv" onClick={() => toggleModal()}><i className="fa fa- 
                                                pencil-square-o" aria-hidden="true"></i></div>}
            </header>
            <section>
                <p className="margin">Your tax rate: {userState.taxRate * 100}%</p>
            </section>
            <section className="buttonDiv">
                <div onClick={() => addJobHandler()}>
                    Add Job
                </div>
            </section>
            <section>
                <Jobs setJob={props.setJob} />
            </section>
        </main>
</React.Fragment>
);
}

Jobs component:

import UserContext from '../../context/userContext';
//imports
                                 //When I attempt to use this as a function I get a compilation error
const [ userState, setUserState, setJobState ] = useContext(UserContext);

/*The change I'm trying to make
 *const selectJob = setJobState;
 */

const jobClickedHandler = (j) => {
    //I'm trying to use it here
    props.setJob(j);
    //selectJob(j);  <---this instead of props.setJob(j);
    props.history.push("wagetrak/job");
}

//...

const deleteJob = (name) => {
    fetch(
        "http://localhost:8080/wageTrak/" + userState.id + "/" + name,
        {
            method: 'DELETE',
            headers: {
                'Content-type': 'application/json',
                'Access-Control-Allow-Origin': 'localhost:3000/',
                'Access-Control-Allow-Methods': 'DELETE'
            },
        }
                                          //this works as intended
    ).then(res => res.json()).then(res => setUserState(res));
}

//...

return (
    <div className="jobs">
        <ul className="jobs-list">
            {userState.jobs && userState.jobs.map(j => (
                <li className="capitalize" key={j.name}>
                    <div className="job-thumbnail">
                        <div className="job-name" onClick={() => 
                            jobClickedHandler(j)
                        }>{j.name}</div>
                        <div onClick={() => deleteClickedHandler(j.name)}>
                            <i className="fa fa-times delete-button" aria-hidden="true"></i>
                        </div>
                    </div>
                </li>
            )
            )}
        </ul>
    </div>
);
}

Context file:

import React from 'react';

const userContext = React.createContext({});

export default userContext;

Changing the code to what you see commented out above results in the following error:

TypeError: selectJob is not a function at jobClickedHandler (Jobs.js:14) at onClick (Jobs.js:44)...

What am I doing resulting in setJobState not being recognized as a function but setUserState is?

If I need to include more code please let me know.

Thanks in advance.

J-Daniel-S
  • 47
  • 8

1 Answers1

1

Change array destructuring from

const [ userState, setUserState, setJobState ] = useContext(UserContext);

to

const [ userState, setUserState, jobState, setJobState ] = useContext(UserContext);

And even you can directly give your variable name e.g

const [ userState, setUserState, jobState, selectJob ] = useContext(UserContext);

Since array destructuring works on index rather than property name.

Dharman
  • 30,962
  • 25
  • 85
  • 135
tsfahmad
  • 404
  • 4
  • 12