home.

tagged: reactjs

React: Using Refs

Sometimes you want direct access to DOM nodes, instead of using props and state to control them. You use refs for this.
 
You define a ref with React.createRef() and then you set it with <div ref={yourRefName} ...> and then you can use it in componentDidMount or in event listeners etc.
 
The standard example is using a ref to focus a input element:

class AThing extends Component {

  constructor(props) {
    super(props)
    this.myRef = React.createRef()
  }

  componentDidMount() {
    this.myRef.current.focus()
  }

  render() {
    return (
      <input ref={this.myRef} value="highlight" />
    )  
  }
}

You can achieve the same things in functional components with the useRef hook:

function AThing2() {
  var myRef = useRef(null)
  useEffect(() => {
    myRef.current.focus()
  }, [])

  return (
    <input ref={myRef} value="highlight!" />
  )  
}

You can attach hooks to html node and react class components but not react functional components.

javascript reactjs


React: Using react-spring intro

There's a nice animation library for react called react-springs. It uses hooks. So we'll be using hooks.
 
The first thing to look at is the useSpring custom hook. You pass it an object of your css properties (and whatever actually).
 
There's a sub property called from which takes an object of the initial position of the css property.

  const springProps = useSpring({ 
    left: "400px", 
    position: "absolute",
    from: { left: "0px" } 
  })

In this case we translate our left property from zero to four hundred. And we set the position to be absolute.
 
After we set this, we then pass the props into a animated.div component that understands them. The whole thing looks like this:

import { useSpring, animated } from 'react-spring'
...
function App () {
  const springProps = useSpring({ 
    left: "400px", 
    position: "absolute",
    from: { left: "0px" } 
  })
  return (
    <div>
      <animated.div style={springProps}>
        I will slide
      </animated.div>
    </div>
  );
}

And we thus animate.
 
react-spring is a physics based library but we can blissfully ignore that and specify a time in config:

  const springProps = useSpring({ 
    left: "400px", 
    position: "absolute",
    from: { left: "0px" },
    config: { duration: 500 }
  })

You'll also notice this animation starts straight away. We can define when it's run by passing, not an object, but a function to useSpring and getting back the previous props, and a method to set the props:

function App () {
  const [springProps, set] = useSpring(() => ({ 
    left: "0px", 
    position: "absolute"
  }))
  const click = () => {
    set({ left: "400px" })
  }
  return (
    <animated.div 
      style={springProps} 
      onClick={click}>
      I will slide
    </animated.div>
  );
}

I've left out the from part of what we pass to useSpring since the from is now defined, and the to part is now defined with the setter function.
 
PS. You can animate your components inside the animated.div or do const AnimatedThing = animated(Thing) and then do <AnimatedThing style="{springProps}"> but at the moment that means Thing must be a class component, not a functional components, for reasons that are beyond me.

javascript reactjs


React: Using hooks

React created functional components for when you need a component that doesn't have state and now they've released hooks which allow you to use state in functional components. Such is life. They're nice in some extra ways too.
 
Instead of setting state in a component class's constructor, you use useState. You pass it an argument which will be the initial state. And it gives you back that value and the a function to set that state. You can use useState as many times as you want for as much state as you want. Got that? Good?
 
Instead of using componentDidMount etc you use useEffect. The first argument is a function. The second argument can be empty which means that function is run on every render. If it's [] it's run only on component mount. If it's [someValue] then that will only be run when someValue is changed. It's best to give an example at this point:

import React, { useState, useEffect } from 'react';
...
function App2 () {
  const [ count, setCount] = useState(0)
  const click = () => setCount(count+1)

  useEffect(() => {
    setCount(10)
  }, [])

  return (
    <div>
      <div>{count}</div>
      <button onClick={click}>Click</button>
    </div>
  );
}

useState(0) sets an initial count state. setCount can be used to set the state. useEffect is used to set the count state to 10 when the component mounts. In this case it's just used for demonstation purposes. In addition you can return a function from useEffect and that function will be run to clean up after the render or after the compontent unmounted if [] was passed to useEffect.

reactjs javascript


React: Custom hooks

Custom hooks are used to reuse logic. If you understand setState and useEffect then custom hooks are nothing special. Let's create one. They're just normal functions. They return a value too.
 
In our custom hook, we'll use useEffect to run a setTimeout when the component is rendered. It will set some state after a specified timeout. Therefore whatever uses this custom hook refuses this logic.

function useTimeout(timeout) {
  var timeoutHandler
  const [text, setText] = useState("Waiting...")
  useEffect(() => {
    timeoutHandler = setTimeout(() => setText("Waited!"), timeout)
    return () => {
      clearTimeout(timeoutHandler)
    }
  })
  return text
}

We can now refuse this logic in any component. For example:

function App () {
  const text = useTimeout(1000)
  return (
    <div>
      <div>{text}</div>
    </div>
  )
}

The {text} will change after one second from Waiting... to Waited!. There are better use cases.

javascript reactjs


ReactJS: Updating state

We have state in our component. And we can call this.setState from a click listener to update that state. When we update the state the component with effecticently (using virutaldom) redraw itself and any sub components.
 
this.setState takes a object as argument and its values relate to the property names in your state. It updates them.
 
We can call this from a onClick attribute on a HTML tag. The onClick's value is within curly bracked and the javascript is within: onclick={() => console.log("i am some javascript")}
 
We will change our style in our div object so it changes based on a clicked variable in our state.

<html>
  <head>
    <script src="https://unpkg.com/react@16.3.1/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.3.1/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
    <script src="https://unpkg.com/prop-types@15.6.1/prop-types.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script type="text/babel">

    class Hello extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          name: props.name,
          clicked: false,
        };
      }
      render() {
        return (
          <div style={{display: "flex", flexDirection: "row"}}>
            <div style={{color: (this.state.clicked) ? "lightgreen" : "blue" }}>Hello {this.state.name}!</div>
            <button onClick={() => this.setState({clicked: true})}>on acid</button>
          </div>
        );
      }
    }

    ReactDOM.render(
      <div>
        <Hello name="Davey dave dave" />
        <Hello name="Chris" />
        <Hello name="Ahmed" />
        <Hello name="Peter" />
      </div>,
      document.getElementById('root')
    );
  </script>
</html>

javascript reactjs

Page 2 of 4
prev next