两个文本区域略有不同,我无法理解为什么第二个区域不起作用。
const StyledTextarea = styled.textarea`
display: block;
font-size: 20px;
line-height: 40px;
min-height: 120px;
overflow: hidden;
padding: 0 7px;
margin: 0 0 30px;
resize: none;
width: 500px;
`;
const Label = styled.span`
color: ${props => props.green ? '#00BB00' : 'red'};
font-size: 1.5em;
`;
const App = () => {
return(
<div>
<Label green>✅ Textarea1 - Working </Label>
<Textarea1 />
<Label>❌ Textarea2 - Not working </Label>
<Textarea2 />
</div>
)
}
class Textarea1 extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda voluptas deleniti at, molestias in amet dolore voluptatem atque, modi minus ipsam dignissimos...',
scrollHeight: 0,
}
}
onChange(e) {
const t = e.target;
t.style.height = 'auto';
t.style.height = `${t.scrollHeight}px`;
this.setState({value: t.value});
}
render() {
return (
<StyledTextarea
value={this.state.value}
onChange={this.onChange.bind(this)}
/>
);
}
}
class Textarea2 extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda voluptas deleniti at, molestias in amet dolore voluptatem atque, modi minus ipsam dignissimos...',
scrollHeight: 0,
}
}
onChange(e) {
const bugger = e.target;
console.log('style.height before it is set to auto: ', bugger.style.height)
bugger.style.height = 'auto';
console.log('style.height after it is set to auto (obviously): ', bugger.style.height)
console.log('.scroll height: ', bugger.scrollHeight);
this.setState({
scrollHeight: bugger.scrollHeight,
value: bugger.value
});
}
render() {
return (
<StyledTextarea
style={{height: `${this.state.scrollHeight}px`}}
value={this.state.value}
onChange={this.onChange.bind(this)}
/>
);
}
}
两者都使用类似的方式来保持其高度与内容的高度同步。但是,第二个,我认为应该使用新的style.height
(来自更新的状态)重新渲染,不适用新的样式。在控制台上查看有问题的值 - 即使在分配新值后,style.height也会保持“自动”状态。
如果你只按Enter和Backspace,它就可以工作。
我不明白是什么?
答案 0 :(得分:0)
这是一个棘手的问题,与使用React的styled-components库比使用React代码本身更相关。在Textarea1
的渲染中,您正在创建一个传递了样式道具的StyledTextarea
。不幸的是,使用样式化组件创建的组件会忽略此道具。
当使用带有反应的样式组件时,你应该拔出你的道具并将它们应用到你的css,如this code-pen所示:
const styled = styled.default;
const Button = styled.button`
background: red;
border-radius: 8px;
color: white;
height: ${props => props.small ? 40 : 60}px;
width: ${props => props.small ? 60 : 120}px;
`;
class Application extends React.Component {
render() {
return (
<div>
<Button small>Click Me</Button>
<Button large>Click Me</Button>
</div>
)
}
}
ReactDOM.render(<Application />, document.getElementById('content'));
要解决您的问题,您必须在StyledTextArea
中提取您的style.height支持,并在Textarea2.onChange结束时将您的身高重置为''
。以下是包含这些更改的代码。请注意,这会破坏在Textarea1中完成的大小调整:
const styled = styled.default;
const StyledTextarea = styled.textarea`
display: block;
font-family: PT Sans;
font-size: 20px;
line-height: 40px;
min-height: 120px;
overflow: hidden;
padding: 0 7px;
margin: 0 0 30px;
resize: none;
width: 500px;
// one update here
height: ${props => (props.style && props.style.height) ? props.style.height + 'px' : '0px'};
`;
const Label = styled.span`
color: ${props => props.green ? '#00BB00' : 'red'};
font-size: 1.5em;
`;
const App = () => {
return(
<div>
<Label green>✅ Textarea1 - Working </Label>
<Textarea1 />
<Label>❌ Textarea2 - Not working </Label>
<Textarea2 />
</div>
)
}
class Textarea1 extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda voluptas deleniti at, molestias in amet dolore voluptatem atque, modi minus ipsam dignissimos...',
scrollHeight: 0,
}
}
onChange(e) {
const t = e.target;
t.style.height = 'auto';
t.style.height = `${t.scrollHeight}px`;
this.setState({value: t.value});
}
render() {
return (
<StyledTextarea
value={this.state.value}
onChange={this.onChange.bind(this)}
/>
);
}
}
class Textarea2 extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda voluptas deleniti at, molestias in amet dolore voluptatem atque, modi minus ipsam dignissimos...',
scrollHeight: 0,
}
}
onChange(e) {
const bugger = e.target;
console.log('style.height before it is set to auto: ', bugger.style.height)
bugger.style.height = 'auto';
console.log('style.height after it is set to auto (obviously): ', bugger.style.height)
console.log('.scroll height: ', bugger.scrollHeight);
this.setState({
scrollHeight: bugger.scrollHeight,
value: bugger.value
});
// another update here
bugger.style.height = '';
}
render() {
console.log(this.state.scrollHeight);
return (
<StyledTextarea
style={{height: this.state.scrollHeight}}
value={this.state.value}
onChange={this.onChange.bind(this)}
/>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
最后一点,您使用的第二种方法肯定是更优选的方法!通过处理程序而不是渲染方法修改组件样式并不理想。