[英]React - render CSS animation onClick
我是React的新手,如果这太基础了,对不起。
我试图在React中单击<Link>
时渲染一个简单的动画。
我有Coffees.jsx :
import Brewing from './Brewing.jsx';
handleClick() {
return (<Brewing/>)
}
render(){
return (
<div>
<div>
<Link onClick={this.handleClick} to="/brewing">Coffee</Link>
</div>
</div>
);
}
}
export default Menus;
和Brewing.jsx :
import './css/mug.css'
class Brewing extends Component {
constructor (props) {
super(props);
};
render() {
return (
<div>
<div className="cup">
<div className="coffee"></div>
</div>
<div className="smoke"></div>
</div>
);
}
}
export default Brewing;
上面的方法不起作用。 仅当我注入动画时才有效:
<div className="cup">
<div className="coffee"></div>
</div>
<div className="smoke"></div>
直接进入Coffees.jxs ,就像这样:
render(){
return (
<div>
<div>
<div className="cup">
<div className="coffee"></div>
</div>
<div className="smoke"></div>
<Link to="/brewing"></Link>
</div>
</div>
);
}
但这是不希望的...我如何在onClick
渲染此动画?
编辑:
App.jsx
class App extends Component {
constructor() {
super();
this.state = {
users: [],
isAuthenticated: false,
messageName: null,
messageType: null,
select:'',
email: '',
id: '',
username: '',
active: '',
admin: '',
//task:''
};
this.logoutUser = this.logoutUser.bind(this);
this.loginUser = this.loginUser.bind(this);
this.createMessage = this.createMessage.bind(this);
this.removeMessage = this.removeMessage.bind(this);
this.userId = this.userId.bind(this);
};
componentWillMount() {
if (window.localStorage.getItem('authToken')) {
this.setState({ isAuthenticated: true });
};
};
componentDidMount() {
this.getUsers();
this.userId();
};
getUsers() {
axios.get(`${process.env.REACT_APP_WEB_SERVICE_URL}/users`)
.then((res) => { this.setState({ users: res.data.data.users }); })
.catch((err) => { });
};
logoutUser() {
window.localStorage.clear();
this.setState({ isAuthenticated: false });
};
loginUser(token) {
window.localStorage.setItem('authToken', token);
this.setState({ isAuthenticated: true });
this.getUsers();
this.createMessage('Welcome', 'success');
};
userId(event) {
const options = {
url: `${process.env.REACT_APP_WEB_SERVICE_URL}/auth/status`,
method: 'get',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
};
return axios(options)
.then((res) => {
console.log(res.data.data)
this.setState({
select: res.data.data.select,
email: res.data.data.email,
id: res.data.data.id,
username: res.data.data.username,
active: String(res.data.data.active),
admin: String(res.data.data.admin),
})
})
.catch((error) => { console.log(error); });
};
createMessage(name='Sanity Check', type='success') {
this.setState({
messageName: name,
messageType: type
});
setTimeout(() => {
this.removeMessage();
}, 3000);
};
removeMessage() {
this.setState({
messageName: null,
messageType: null
});
};
render() {
return (
<div>
<NavBar
title={this.state.title}
isAuthenticated={this.state.isAuthenticated}
/>
<section className="section">
<div className="container">
{this.state.messageName && this.state.messageType &&
<Message
messageName={this.state.messageName}
messageType={this.state.messageType}
removeMessage={this.removeMessage}
/>
}
<div className="columns">
<div className="column is-half">
<br/>
<Switch>
<Route exact path='/about' component={About}/>
<Route exact path='/register' render={() => (
<Form
formType={'Register'}
isAuthenticated={this.state.isAuthenticated}
loginUser={this.loginUser}
createMessage={this.createMessage}
userId={this.state.id}
/>
)} />
<Route exact path='/login' render={() => (
<Form
formType={'Login'}
isAuthenticated={this.state.isAuthenticated}
loginUser={this.loginUser}
createMessage={this.createMessage}
userId={this.state.id}
/>
)} />
<Route exact path='/logout' render={() => (
<Logout
logoutUser={this.logoutUser}
isAuthenticated={this.state.isAuthenticated}
/>
)} />
<Route exact path='/status' render={() => (
<UserStatus
isAuthenticated={this.state.isAuthenticated}
/>
)} />
<Route exact path='/seeds' render={() => (
<Seeds
isAuthenticated={this.state.isAuthenticated}
userId={this.state.id}
/>
)} />
<Route exact path='/menus' render={() => (
<Menus
isAuthenticated={this.state.isAuthenticated}
userId={this.state.id}
/>
)} />
<Route exact path='/coffee' render={() => (
<Coffees
isAuthenticated={this.state.isAuthenticated}
userId={this.state.select}
/>
)} />
</Switch>
</div>
</div>
</div>
</section>
</div>
)
}
};
export default App;
Menus
组件需要考虑一些事项。
handleClick()
返回<Brewing>
JSX不会影响Menus
组件的渲染结果,这意味着<Brewing>
中的动画不会按要求显示 <Link>
,此时Menus
组件可以呈现<Brewing>
组件(即包含动画的组件) 在代码中解决此问题的一种方法是在Coffee.jsx中进行以下更改:
import Brewing from './Brewing.jsx'; class Menus extends React.Component { constructor(props) { super(props); /* Set inital state to false, which means Brewing wont initially show */ this.state = { hasBeenClicked : false }; } } handleClick() { /* Set hasBeenClicked state of Menus to true after click which will cause Brewing to be rendered */ this.setState({ hasBeenClicked : true }); } render(){ return ( <div> <div> { /* This is short hand for "if hasBeenClicked = true, then render Brewing here */ } { (this.state.hasBeenClicked === true) && <Brewing/> } <Link onClick={this.handleClick} to="/brewing">Coffee</Link> </div> </div> ); } } export default Menus;
当您单击任何Link
它不会等待该组件执行任何事件,它将仅redirect
到给定路径(to="/coffees")
,因此您需要使用Route来处理该路径。
除了Link
我们可以使用button
或简单地使用div
(您可以对其进行样式设置,使其看起来像链接),然后在其上编写onClick
处理程序。 在该处理程序中,我们需要添加一个setTimeout
和实际动画的超时时间。
现在,当setTimeout
执行时,我们可以将变量设置为state
,这将帮助我们重定向到所需的组件。
您的菜单组件应为
class Menu extends React.Component{
constructor(props){
super(props);
this.state = {
isLoading: false,
redirect: false
}
}
gotoCoffee = () => {
this.setState({isLoading:true})
setTimeout(()=>{
this.setState({isLoading:false,redirect:true})
},5000) //Replace this time with your animation time
}
renderCoffee = () => {
if (this.state.redirect) {
return <Redirect to='/coffees' />
}
}
render(){
return(
<div>
{this.state.isLoading && <Brewing />}
{this.renderCoffee()}
<div onClick={this.gotoCoffee} style={{textDecoration:'underline',color:'blue',cursor:'pointer'}}>Go to Coffee</div>
</div>
)
}
}
我已经使用从react-router-dom
包中的Redirect
进行导航。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.