Bor*_*rsn 4 javascript addeventlistener reactjs styled-components
在调整大小时,甚至不会触发侦听器。
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.containerRef = React.createRef();
this.state = {};
}
componentDidMount() {
this.containerRef.current.addEventListener("resize", this.handleResize);
}
componentWillUnmount() {
this.containerRef.current.removeEventListener("resize", this.handleResize);
}
handleResize() {
console.log("handleResize");
}
render() {
return (
<React.Fragment>
<Container ref={this.containerRef}>
<Body />
</Container>
<ShadowTop show={this.state.top} />
</React.Fragment>
);
}
}
Run Code Online (Sandbox Code Playgroud)
--
export const Container = styled.div`
@media (max-width: 760px) {
position: absolute;
}
margin-top: ${({ theme }) => theme.header.height.percent}%;
margin-top: -webkit-calc(${({ theme }) => theme.header.height.pixel}px);
margin-top: -moz-calc(${({ theme }) => theme.header.height.pixel}px);
margin-top: calc(${({ theme }) => theme.header.height.pixel}px);
height: ${({ theme }) => Math.abs(100 - theme.header.height.percent)}%;
height: -webkit-calc(100% - ${({ theme }) => theme.header.height.pixel}px);
height: -moz-calc(100% - ${({ theme }) => theme.header.height.pixel}px);
height: calc(100% - ${({ theme }) => theme.header.height.pixel}px);
position: fixed;
float: none;
clear: both;
top: 0;
right: 0;
width: ${({ theme }) => 100 - theme.sidebar.width.percent}%;
width: -webkit-calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
width: -moz-calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
width: calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
z-index: 2;
pointer-events: auto;
overflow: auto;
`;
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么?
我试图检测div又名Container元素何时styled-components改变大小。
该resize事件在 上触发window,而不是在单个元素上触发。这是因为该resize事件旨在处理视口调整大小,而不是内容调整大小。要检测内容大小的变化,您可以使用ResizeObserver.
您可以通过多种方式将其合并到您的 React 项目中。这是一个与您在问题中遇到的类似的示例:
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.ulRef = React.createRef();
this.state = { todoList: [] };
// Binding methods to the current intance is only needed if you pass
// the method as an argument to another function and want acces to the
// `this` keyword in the method.
this.handleResize = this.handleResize.bind(this);
this.addTodoItem = this.addTodoItem.bind(this);
}
componentDidMount() {
this.ulObserver = new ResizeObserver(this.handleResize);
this.ulObserver.observe(this.ulRef.current);
}
componentWillUnmount() {
this.ulObserver.disconnect();
}
handleResize(entries, observer) {
console.log("handleResize", entries);
// ...
}
addTodoItem(event) {
event.preventDefault();
const formData = new FormData(event.target);
this.setState((state) => ({
todoList: [...state.todoList, formData.get("todo-item")],
}));
}
render() {
return (
<div>
<form onSubmit={this.addTodoItem}>
<input name="todo-item" />
<button>add</button>
{" "}(or press <kbd>Enter</kbd>)
</form>
<ul ref={this.ulRef}>
{this.state.todoList.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
}
ReactDOM.render(<MainContainer />, document.querySelector("#root"));Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
可能还有一些库可以帮助您组合ResizeObserver和 React。但了解幕后发生的事情并没有什么坏处。
对于那些寻求更现代的功能组件解决方案的人:
const { createRef, useState, useCallback, useEffect } = React;
function MainContainer() {
const ulRef = createRef();
const [todoList, setTodoList] = useState([]);
const addTodoItem = useCallback(function (event) {
event.preventDefault();
const formData = new FormData(event.target);
setTodoList(todoList => [...todoList, formData.get("todo-item")]);
}, []);
const handleResize = useCallback(function (entries, observer) {
console.log("handleResize", entries);
// ...
}, []);
useEffect(function () {
const ulObserver = new ResizeObserver(handleResize);
ulObserver.observe(ulRef.current);
return () => ulObserver.disconnect();
}, [handleResize]);
return (
<div>
<form onSubmit={addTodoItem}>
<input name="todo-item" />
<button>add</button>
{" "}(or press <kbd>Enter</kbd>)
</form>
<ul ref={ulRef}>
{todoList.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</div>
);
}
ReactDOM.createRoot(document.querySelector("#root")).render(<MainContainer />);Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2501 次 |
| 最近记录: |