1

In order to study the react framework, I've been developing a simple web application to rate books. It's currently looking like this:

enter image description here

And the idea of the side bar is simple enought: it's width will be 0 when hidden, and when I click a open menu button it will be set to another width.

The code behind it all is looking like this:

import React from 'react';
import { Link } from 'react-router-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import home from '../../image/side-nav/home.png';
import list from '../../image/side-nav/list.png';
import '../../css/SideNavBar.css'
import * as utils from '../../scripts/utils.js'; 

const SideNavBar = () =>{
    return(
        <Router>
            <div>
                <span className="spanOpen" onClick={utils.openNav()}>&#9776;</span>
                <div className="sidenav">
                    <a className='closebtn' onClick={utils.closeNav()}>&times;</a>
                    <ul>
                        <li>
                            <Link to='/'><img src={home} alt='Home' /><span className='h-item'>Home</span></Link>
                        </li>
                        <li>
                            <Link to='/books'><img src={list} alt='Books' /><span className='b-item'>Books</span></Link>
                        </li>
                    </ul>
                    <div className='sidenav-footer'>
                        <hr />
                        <small>Pelicer &copy; 2018</small>
                    </div>
                </div>
            </div>
        </Router>
    );
}
export default SideNavBar;

And here is the code of the util.js file, which contains the the fucntions to change:

export function openNav() {
    // document.getElementsByClassName("sidenav")[0].style.width = "315px";
}

export function closeNav() {
    // document.getElementsByClassName("sidenav")[0].style.width = "0";
}

But when I run it, I get the error: TypeError: Cannot read property 'style' of undefined. It happens because it is trying to change the width of somethings that has not yet been created. What I want to do, and tried using componentDidMount, is to import the JavaScript after the HTML has been rendered, in a way that when it sets the width, the component is already there. Can someone help out in a solution?

3
  • Who's trying to change the width of something that has not been created? Commented Mar 13, 2018 at 17:24
  • My bad, @DragoşPaulMarinescu. I've eddited the question with aditional code. Commented Mar 13, 2018 at 17:26
  • 2
    I think you need to rethink how you show/hide the sidenav in a React-like approach. What you're doing now is vanilla javascript. Commented Mar 13, 2018 at 17:27

1 Answer 1

1

You're calling the utils.xyz functions too soon. This:

<span className="spanOpen" onClick={utils.openNav()}>&#9776;</span>

calls utils.openNav and uses its return value as the value of the onClick. You probably meant:

<span className="spanOpen" onClick={utils.openNav}>&#9776;</span>

(without the ()) to just refer to the function. That will work if utils.openNav doesn't need this to refer to utils during the call. If it does need this to be utils during the call:

<span className="spanOpen" onClick={() => utils.openNav()}>&#9776;</span>

...which defines a function and uses that function as the value of onClick.

In that case where this matters, probably better to change that functional component to a class component, create that function once, and reuse it:

class SideNavBar extends React.Component {
    constructor() {
        this.openNav = () => utils.openNav();
        // ...
    }
    // ...
}

and then in render:

<span className="spanOpen" onClick={openNav}>&#9776;</span>
Sign up to request clarification or add additional context in comments.

4 Comments

Actually, it would be better to do onClick={utils.openNav} (just removing the parenthesis) and not declaring a function in each render.
@FacundoMatteo: Only if utils.openNav doesn't care what this is when it's called. I chose not to make that assumption, but can clarify.
@FacundoMatteo: Did that now.
Thanks, @T.J.Crowder. I'll look into syntax a little more. And, as stated in other comments, try to 'think the react way' when trying to resolve problems like this one in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.