Using history.push correctly - reactjs

I want to use history.push to link to another page on my React app upon a button click but when I use history.push, it gives me the error Unexpected use of 'history'.(no-restricted-globals)
<ExampleComponent handleClick={history.push('/path/to/page')} text={'something'} />
Inside the ExampleComponent, I have a button with an onClick handler that calls the handleClick props
<Button onClick={() => this.props.handleClick}>{this.props.text}</Button>

update
When you use ExampleComponent component there is a problem with the variable history. As this is globally reachable as windows.history. I think you call history.push the linter gives a warning if it is window.history or not.

Related

React: findDOMNode was passed an instance of Transition

I very new to React, and have run into an issue, which I really cant seem to find any solution on...
Basically, I have a button which triggers a state to open/hide a modal component... When clicking the button, im getting the error:
index.js:1 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here:
So I tried adding a ref to my Modal component, didnt work, also tried creating a wrapper around the Modal component with a ref, didn't help either?
I got the error after adding the connect() from redux - Before adding the connect() method to the component, I didn't get an error?
The code is VERY simple:
<div>
<button onClick={toggleTrueFalse}>Click here to open a modal</button>
<CSSTransition
in={showModal}
timeout={300}
classNames="dialog"
unmountOnExit
>
<Modal modalHeaderContent={modalHeaderContent} modalContent={modalContent}/>
</CSSTransition>
</div>
the method to change the state of the modal is:
const [showModal, setShowModal] = useState(false);
const toggleTrueFalse = () => setShowModal(!showModal);
Im guessing the solution would be rather simple, but just cant seem to find any solution ?
Ok, so I found a working solution as the GIThub page of react-transition-group:
https://github.com/reactjs/react-transition-group/issues/668

React onClick on stateless component

I have been trying to fire an onClick on a react component. The event fires if I use
<button onClick={()=>this.goToPage('next')}>Next Page</button>
If I use the same method on a stateless component, it doesn't fire:
<PageButton onClick={()=>this.goToPage('next')}>Next Page</PageButton>
Why this is not possible?
Because what you are defining is a custom component. Note, that everything that you provide to the custom component is considered as props. So, your onClick method is also provided as props. Essentially you'll be required to do -
<PageButton onClick={()=>this.goToPage('next')}>Next Page</PageButton>
and in your <PageButton /> component -
<button onClick={this.props.onClick}>Next Page</button>
if you know what props you are providing to this component and not providing any unnecessary props, you can even spread the props object, like -
<button {...this.props}>Next Page</button>
Note - If you have other props to provide to this component as well, kindly refrain from using this method, as this will result in many unrecognized function warnings.
PS: Even if you write
<PageButton style={{backgroundColor: 'red}}>Next Page</PageButton>
it won't work because, this is treated as a prop. You'll need to handle the style prop in the render method of this <PageButton/> component
This does not work on a stateless component because the onClick is considered as a prop rather a event listener , you should implement.
For example inside PageButton you should implement something like this
render(){
return <div onClick={()=>this.props.onClick('next')}/>
}

Reactjs Button with dynamic link

I am using the Material-UI React components.
I have a Button that has a Link to a specific page.
When I update my state ( username in the example below ), should I expect the link to change too or do I need to force an update to the href of the button when I update my state.username ?
<Button component={Link} to={`meeting/${this.state.username}`} variant="raised" color="primary">
Render method of React Components is being called on every state change as long as you update the state properly.
So, answering your question: you should expect the link to change too.
You have to update the state and the link will be updated automatically as the component renders itself on setState
Use this way to update your state rather than updating it directly.
this.setState({username:"newUserName"});

Testing for text contained in React component with Enzyme and Jest

For my React component I have the following:
const ArchiveButton = ({collection, onClick}) => {
return (
<span>
{ collection.archived &&
<Button bsStyle="link" onClick={onClick}><i className="fa fa-rotate-left" /> Unarchive</Button>
}
{ !collection.archived &&
<Button bsStyle="link" onClick={onClick}><i className="fa fa-archive" /> Archive</Button>
}
</span>
);
};
I'm attempting to test by passing in different values for collection.archived and I want to check for the existence of the text "Unarchive" vs "Archive". When I do a wrapper.find('Button') and try and check against .text() it is just <Button /> and the only way I've figured out how to test it is:
const wrapper = shallow(<ArchiveButton onClick={onClick} {...props}/>);
let button = wrapper.find('Button').prop('children');
expect(button[1]).toMatch(/\sUnarchive/);
Seems a bit off though, not sure. Thanks!
It's because you're using shallow rendering, so your nested Button component doesn't get rendered. As you've seen, you can access the nested component props to test the values you pass to it.
If you prefer to have the button content rendered, use normal rendering instead.
Note that the nested Button is not a normal DOM element, which would be rendered anyway even if you use shallow rendering, but it's instead a component itself.
If you think about it, if you don't use shallow rendering in your case, you're not really unit-testing your component, as you're also asserting something about the Button component. If you use shallow rendering and access the props of the nested component, you're really just testing that your code is calling the Button component with the correct arguments, and you're not making any assumptions as how the Button component will render.
This is normally what you want to do in a unit test.

Can I pass the selected tab back from onTouchTap event of Material-UI Tabs component?

I'm using the Material-UI Tabs component in my ReactJS app.
I'm handling the onTouchTap event of the Tabs component. I'd like to pass the currently selected tab back as a parameter to the event handler.
Is this possible?
So something like this
<Tabs onChange={props.onChangePosition}
onTouchTap={e => {/* What */}>
I know that the onChange handler returns it, but I'd like to use onTouchTap in this instance.
Yes, this can be done. You need to capture a "ref" to your Tabs control, and then call getSelectedIndex() on it, inside your onTouchTap. getSelectedIndex is somewhat internal, so it has an unexpected method signature in that you must also pass it in its own props.
<Tabs
ref={ref => (this.tabs = ref)}
onTouchTap={(e) => console.log(this.tabs.getSelectedIndex(this.tabs.props))}
>
...

Resources