can I use variable declared within a function as a parameter for another function nested inside the function?

Viewed 66

I am trying to create a function which basically look like this:

function parentFunction (){
    
    const [a,setA]=useState(false);
    
    function nestedFunction (a){
        if (a===false){do something} 
        else if (a===true){do something}
    
        return something
    }

My main question is can I use the local variable created within the parent function as parameter for the nested function?

This is link to codesandbox, not sure whether the link can be shared like this.

https://codesandbox.io/s/es6-spread-operator-practice-forked-crqec?file=/src/components/ListItem.jsx

2 Answers

By the general principle of Scope in Javascript. Outer variables can be accessed by the inner function. Also, in Javascript we have Closures, so even after the inner function returns, it can still access the outer variable.

Note that because your parameter name to the function is also a. And state variable is a as well, inn your nestedFunction(a), a will point to parameter a being passed to it, not the state variable a because of its Scope.

Also I want to point out a state variable is already a boolean, you don't explicitly need to use a===false simple use the variable name with ! operator.

Like this:

function parentFunction (){

const [a,setA]=useState(false);

function nestedFunction(a){
    if (!a){ // a pointing to the parameter variable a not the state variable a
      do something
    } 
    else{
     //do something else
    }

    return something
 }
}

UPDATE: From codesandbox link and your comment, It is clear that you are trying to toggle the listItem style text-decoration:line-through;

I have made some modifications to the code so that it works fine, Just used an external style instead of inline one and did a very basic validation.

CODESANDBOX LINK: https://codesandbox.io/s/the-todoapp-with-nice-css-i7dy7

FULL WORKING CODE SNIPPET:

const {useState} = React;

function App() {
  const [item, setItem] = useState("");
  const [items, setItems] = useState([]);

  function handleChange(event) {
    const newItem = event.target.value;
    setItem(newItem);
  }

  function handleAdd() {
    if (item) {
      setItems((preValues) => [...preValues, item]);
      setItem("");
    }
  }

  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input type="text" onChange={handleChange} value={item} required />
        <button onClick={handleAdd}>
          <span>Add</span>
        </button>
      </div>
      <div>
        <ul>
          {items.map((item) => (
            <List butt={item} />
          ))}
        </ul>
      </div>
    </div>
  );
}


function List(props) {
  const [isClicked, setIsClicked] = useState(false);

  function handleClicked() {
    setIsClicked((preValue) => !preValue);
  }

  return (
    <li onClick={handleClicked} className={`listItem ${isClicked ? "li-clicked" : ""}`}>
      {props.butt}
    </li>
  );
}

ReactDOM.render(<App/>, document.getElementById("root"));
body {
  background-color: #ffeaa7;
  min-height: 70vh;
  padding: 1rem;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  color: hsl(198, 1%, 29%);
  font-family: "Architects Daughter", cursive;
  text-align: center;
  font-size: 130%;
}

.container {
  width: 100%;
  height: auto;
  min-height: 500px;
  max-width: 500px;
  min-width: 250px;
  background: #f1f5f8;
  background-image: radial-gradient(#bfc0c1 7.2%, transparent 0);
  background-size: 25px 25px;
  border-radius: 20px;
  box-shadow: 4px 3px 7px 2px #00000040;
  padding: 1rem;
  box-sizing: border-box;
}
.heading {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;
}
.heading h1 {
  transform: rotate(2deg);
  padding: 0.2rem 1.2rem;
  border-radius: 20% 5% 20% 5%/5% 20% 25% 20%;
  background-color: #fdcb6e;
  font-size: 1.5rem;
}

.form input {
  box-sizing: border-box;
  background-color: transparent;
  padding: 0.7rem;
  border-bottom-right-radius: 15px 3px;
  border-bottom-left-radius: 3px 15px;
  border: solid 3px transparent;
  border-bottom: dashed 3px #fdcb6e;
  font-family: "Architects Daughter", cursive;
  font-size: 1rem;
  color: hsla(260, 2%, 25%, 0.7);
  width: 70%;
  margin-bottom: 20px;
}

button {
  padding: 0;
  border: none;
  font-family: "Architects Daughter", cursive;
  text-decoration: none;
  padding-bottom: 3px;
  border-radius: 5px;
  background-color: #ffeaa7;
}
button span {
  background: #f1f5f8;
  display: block;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  border: 2px solid hsl(198, 1%, 29%);
}

li {
  text-align: left;
  position: relative;
  padding: 0.5rem;
}


.listItem {
  cursor: pointer !important;
}

.listItem.li-clicked {
  text-decoration: line-through;
}
<div id="root"></div>

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

If you do this a variable inside nested function is different from a variable in outer function and it's called variable shadowing. you can call the input of the function whatever_name_you_like but it's another variable unless you explicitly pass the a variable to the function.

function parentFunction() {
  const [a, setA] = useState(false);

  function nestedFunction(Im_a_different_variable) {
    if (Im_a_different_variable === false) {
      //do something
    } else if (Im_a_different_variable === true) {
      //do something
    }

    return something;
  }
}

If you pass a as input to nestedFunction it would be the value of a when you're calling the nested function

function parentFunction() {
  const [a, setA] = useState(false);

  function nestedFunction(Im_a_different_variable) {
    if (Im_a_different_variable === false) {
      //do something
    } else if (Im_a_different_variable === true) {
      //do something
    }

    return something;
  }

  nestedFunction(a); // now the argument of the nested function has the value of a at this time
}
Related