1

I am trying to redirect to the new component once it has been made. Imagine a creator prompt that asks for a name, once they hit create I redirect them to that component.

I don't quite understand why the following works:

class myComponent extends Component{
    constructor(props){
        super(props);
        this.state = {
            redirect: false,
        }
     }

    setRedirect = () => {
       this.setState({
            redirect: true
        })
    }

    doRedirect = () => {
        if(this.state.redirect){
            return <Redirect to='/newComponent'/>
        } 
    }

    <Button type="Submit" onClick={this.setRedirect}>
        Go!
    </Button>

But this does not work:

doRedirect = () => {
    <Redirect to='/newComponent'/>
}

<Button type="Submit" onClick={this.doRedirect()}>
    Go!
</Button>

I am also trying to pass props which is not shown in the code above. Why does redirect need to be associated with a boolean to work?

devserkan
  • 16,870
  • 4
  • 31
  • 47
Justin
  • 9
  • 2
  • 1
    performs redirection when it is rendered. It has nothing to do with boolean logic. And the code that you pasted here does not make sense. For starters, where's the render method? Also, the doRedirect method is never called in the first example, and it will not get called automagically, so I don't see how the whole thing would work. Finally, one crucial difference in the example that "does not work" is that you never return the element from doRedirect(). If this doesn't help you, please provide some full working/not-working fiddles :) – Avius Jul 20 '18 at 16:42

2 Answers2

0

The problem lies with you returning the <Redirect /> object in a function that is not the render() function.

Try this (Untested code):

class myComponent extends Component{
    constructor(props){
        super(props);

        this.state = {
            redirect: false,
        }
     }

    setRedirect = () => {
       this.setState({
            redirect: true
        })
    }

    render() {
        return (
            <Button type="Submit" onClick={this.setRedirect}>
                {this.state.redirect} && <Redirect to='/newComponent'/>
                Go!
            </Button>
        );
    }
}

Changes made: - Make sure you return your component in the render() method.

eqwert
  • 507
  • 6
  • 15
0

The second one does not work because the logic is probably not suitable for the component.

First of all Redirect is not related to a boolean logic. When you use it somewhere in your render method, it redirects whatever path you provided it. You just bind it to a condition (if needed) to do the redirect. This bind could be a boolean logic or something else to check the condition.

You haven't provided the full code, especially the render method but working code is probably something like this:

class myComponent extends Component {
    constructor(props){
        super(props);
        this.state = {
            redirect: false,
        }
     }

    setRedirect = () => {
       this.setState({
            redirect: true
        })
    }

    doRedirect = () => {
        if(this.state.redirect){
            return <Redirect to='/newComponent'/>
        } 
    }

    render() {
        return (
            <div>
                <Button type="Submit" onClick={this.setRedirect}>
                    Go!
                </Button>
                {this.doRedirect()}
            </div>
        )
    }
}

Here as you can see we are invoking doRedirect function in the render method. But, since initial redirect state is false, nothing returns from this function. We only see our button here. When we click the button it updates the state, component rerenders, doRedirect function runs again but this time it returns Redirect component and component renders it.

Here is your second code with your logic with the return in doRedirect as @Avious pointed out in the comment. If you don't use a return there (or properly use the arrow function, which means removing curly braces to use a shorthand return) you can't get anything from it.

class myComponent extends Component {
    constructor(props){
        super(props);
        this.state = {
            redirect: false,
        }
     }

    setRedirect = () => {
       this.setState({
            redirect: true
        })
    }

    doRedirect = () => {
            return <Redirect to='/newComponent'/>
    }

    render() {
        return (
            <div>
                <Button type="Submit" onClick={this.doRedirect()}>
                    Go!
                </Button>
                {this.doRedirect()}
            </div>
        )
    }
}

There are two problems here. First one is you are immediately invoking a function in the button. This is not the way we use a callback function in a button. A button uses a callback function like this:

<Button type="Submit" onClick={() => this.doRedirect()}>
    Go!
</Button>

When we click the button it invokes its callback function and this function does something, here invoking another function.

Second problem is that, button here is unnecessary! We are already invoking doRedirect function in the render method and since there is no condition like state in the previous example it returns Redirect immediately in the first render.

So, the right logic is binding the Redirect to a condition or an operation and check the outcome from it, then do the redirect.

devserkan
  • 16,870
  • 4
  • 31
  • 47