我想创建一个包装器组件,它的行为类似于react- native
s<TouchableOpacity/>
而无需使用react-native-web
.
我正在考虑管理状态并使用从.5
到的内联样式转换1
为不透明度的东西,setInterval
或者它应该是一个 css 转换。
那里已经有东西了吗?
最好的方法是什么?
我想创建一个包装器组件,它的行为类似于react- native
s<TouchableOpacity/>
而无需使用react-native-web
.
我正在考虑管理状态并使用从.5
到的内联样式转换1
为不透明度的东西,setInterval
或者它应该是一个 css 转换。
那里已经有东西了吗?
最好的方法是什么?
您可以通过 css 转换和使用状态来跟踪用户单击按钮的时间来实现此效果:
class App extends React.Component {
state = {
touched: false
}
toggleTouched = () => {
this.setState( prevState => ({
touched: !prevState.touched
}));
}
handleMouseUp = () => {
// Handle smooth animation when clicking without holding
setTimeout( () => {
this.setState({ touched: false });
}, 150);
}
render () {
const { touched } = this.state;
const className = touched ? 'btn touched' : 'btn';
return (
<button
className={className}
onMouseDown={this.toggleTouched}
onMouseUp={this.handleMouseUp}
>
Touch Here
</button>
)
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
.btn {
background: #ededed;
padding: 10px 15px;
border: none;
outline: none;
cursor: pointer;
font-size: 15px;
opacity: 1;
transition: opacity 300ms ease;
}
.touched {
opacity: 0.5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
@ChaseDeAnda 的答案真的很棒。我已经制作了它的打字稿组件版本
TouchableOpacity.tsx
import React from 'react'
import classNames from 'classnames'
import styles from './index.module.scss'
export default function TouchableOpacity({ className, children, ...rest }: TTouchableOpacityProps) {
const [touched, touchedSet] = React.useState(false)
return (
<button
className={classNames(styles.container, className)}
style={{ opacity: touched ? 0.5 : 1, transition: 'opacity 300ms ease' }}
onMouseDown={() => touchedSet(true)}
onMouseUp={() => touchedSet(false)}
{...rest}>
{children}
</button>
)
}
类型.d.ts
type TTouchableOpacityProps = React.ButtonHTMLAttributes<HTMLButtonElement>
(您不必使用“类名”包 - 字符串插值就可以了)