Diff
checker
Text
Text
Bilder
Dokumente
Excel
Ordner
Legal
Enterprise
Desktop-App
Preise
Einloggen
Diffchecker Desktop herunterladen
Texte vergleichen
Finde den Unterschied zwischen zwei Textdateien
Werkzeuge
Verlauf
Live-Editor
Gleiches ausblenden
Zeilenumbruch aus
Ansicht
Zweispaltig
Einspaltig
Vergleichsgenauigkeit
Intelligent
Wort
Zeichen
Syntaxhervorhebung
Syntax auswählen
Ignorieren
Text umwandeln
Zur ersten Änderung
Eingabe bearbeiten
Diffchecker Desktop
Der sicherste Weg, Diffchecker zu nutzen. Hol dir die Desktop-App: Deine Diffs verlassen nie deinen Computer!
Desktop holen
vscode插件i18n-automatically扫描前后jsx的对比图
Erstellt
vor 2 Jahren
Diff läuft nie ab
Löschen
Exportieren
Teilen
Erklären
24 Entfernungen
Zeilen
Gesamt
Entfernt
Zeichen
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
194 Zeilen
Kopieren
84 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Zeichen
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
237 Zeilen
Kopieren
Kopieren
Kopiert
Kopieren
Kopiert
// test.jsx
import i18n from '@/i18n';
// test.jsx
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import PropTypes from 'prop-types';
// 模拟的 API 调用函数
// 模拟的 API 调用函数
const fetchUserData = () => {
const fetchUserData = () => {
return new Promise((resolve) => {
return new Promise((resolve) => {
setTimeout(() => {
setTimeout(() => {
resolve({
resolve({
Kopieren
Kopiert
Kopieren
Kopiert
name:
'张三'
,
name:
i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-1')
,
age: 30,
age: 30,
Kopieren
Kopiert
Kopieren
Kopiert
occupation:
'软件工程师'
,
occupation:
i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-2')
,
});
});
}, 1000);
}, 1000);
});
});
};
};
// 错误边界组件
// 错误边界组件
class ErrorBoundary extends React.Component {
class ErrorBoundary extends React.Component {
constructor(props) {
constructor(props) {
super(props);
super(props);
this.state = { hasError: false, error: null };
this.state = { hasError: false, error: null };
}
}
static getDerivedStateFromError(error) {
static getDerivedStateFromError(error) {
return { hasError: true, error };
return { hasError: true, error };
}
}
componentDidCatch(error, errorInfo) {
componentDidCatch(error, errorInfo) {
console.error('错误边界捕获到错误:', error, errorInfo);
console.error('错误边界捕获到错误:', error, errorInfo);
}
}
render() {
render() {
if (this.state.hasError) {
if (this.state.hasError) {
Kopieren
Kopiert
Kopieren
Kopiert
return
<h2>
很抱歉,出现了错误:
{this.state.error.message}
</h2>
;
return
(
<h2>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-3')}
{this.state.error.message}
</h2>
)
;
}
}
return this.props.children;
return this.props.children;
}
}
}
}
// 头部组件
// 头部组件
const Header = ({ title }) => (
const Header = ({ title }) => (
<header>
<header>
<h1>{title}</h1>
<h1>{title}</h1>
<nav>
<nav>
<ul>
<ul>
<li>
<li>
Kopieren
Kopiert
Kopieren
Kopiert
<a href="#home">
首页
</a>
<a href="#home">
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-4')}
</a>
</li>
</li>
<li>
<li>
Kopieren
Kopiert
Kopieren
Kopiert
<a href="#about">
关于我们
</a>
<a href="#about">
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-5')}
</a>
</li>
</li>
<li>
<li>
Kopieren
Kopiert
Kopieren
Kopiert
<a href="#contact">
联系方式
</a>
<a href="#contact">
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-6')}
</a>
</li>
</li>
</ul>
</ul>
</nav>
</nav>
</header>
</header>
);
);
Header.propTypes = {
Header.propTypes = {
title: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
};
};
// 用户信息组件
// 用户信息组件
const UserInfo = ({ user }) => (
const UserInfo = ({ user }) => (
<div className="user-info">
<div className="user-info">
Kopieren
Kopiert
Kopieren
Kopiert
<h3>
{user.name}
的个人信息
</h3>
<h3>
<p>
年龄:
{user.age}
</p>
{user.name}
<p>
职业:
{user.occupation}
</p>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-7')}
</h3>
<p>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-8')}
{user.age}
</p>
<p>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-9')}
{user.occupation}
</p>
</div>
</div>
);
);
// 计数器组件
// 计数器组件
const Counter = () => {
const Counter = () => {
const [count, setCount] = useState(0);
const [count, setCount] = useState(0);
const increment = () => setCount((prevCount) => prevCount + 1);
const increment = () => setCount((prevCount) => prevCount + 1);
const decrement = () => setCount((prevCount) => prevCount - 1);
const decrement = () => setCount((prevCount) => prevCount - 1);
return (
return (
<div>
<div>
Kopieren
Kopiert
Kopieren
Kopiert
<h3>
计数器
</h3>
<h3>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-10')}
</h3>
<p>
当前计数:
{count}
</p>
<p>
<button onClick={increment}>
增加
</button>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-11')}
<button onClick={decrement}>
减少
</button>
{count}
</p>
<button onClick={increment}>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-12')}
</button>
<button onClick={decrement}>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-13')}
</button>
</div>
</div>
);
);
};
};
// 待办事项组件
// 待办事项组件
const TodoList = () => {
const TodoList = () => {
const [todos, setTodos] = useState([]);
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e) => setInputValue(e.target.value);
const handleInputChange = (e) => setInputValue(e.target.value);
const handleSubmit = (e) => {
const handleSubmit = (e) => {
e.preventDefault();
e.preventDefault();
if (inputValue.trim()) {
if (inputValue.trim()) {
setTodos([
setTodos([
...todos,
...todos,
{ id: Date.now(), text: inputValue, completed: false },
{ id: Date.now(), text: inputValue, completed: false },
]);
]);
setInputValue('');
setInputValue('');
}
}
};
};
const toggleTodo = (id) => {
const toggleTodo = (id) => {
setTodos(
setTodos(
todos.map((todo) =>
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo,
todo.id === id ? { ...todo, completed: !todo.completed } : todo,
),
),
);
);
};
};
return (
return (
<div>
<div>
Kopieren
Kopiert
Kopieren
Kopiert
<h3>
待办事项
</h3>
<h3>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-14')}
</h3>
<form onSubmit={handleSubmit}>
<form onSubmit={handleSubmit}>
<input
<input
type="text"
type="text"
value={inputValue}
value={inputValue}
onChange={handleInputChange}
onChange={handleInputChange}
Kopieren
Kopiert
Kopieren
Kopiert
placeholder=
"输入新的待办事项"
placeholder=
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-15')}
/>
/>
Kopieren
Kopiert
Kopieren
Kopiert
<button type="submit">
添加
</button>
<button type="submit">
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-16')}
</button>
</form>
</form>
<ul>
<ul>
{todos.map((todo) => (
{todos.map((todo) => (
<li
<li
key={todo.id}
key={todo.id}
onClick={() => toggleTodo(todo.id)}
onClick={() => toggleTodo(todo.id)}
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
>
>
{todo.text}
{todo.text}
</li>
</li>
))}
))}
</ul>
</ul>
</div>
</div>
);
);
};
};
// 主应用组件
// 主应用组件
const App = () => {
const App = () => {
const [user, setUser] = useState(null);
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
useEffect(() => {
fetchUserData()
fetchUserData()
.then((data) => {
.then((data) => {
setUser(data);
setUser(data);
setIsLoading(false);
setIsLoading(false);
})
})
.catch((err) => {
.catch((err) => {
Kopieren
Kopiert
Kopieren
Kopiert
setError(
'获取用户数据时出错')
;
setError(
i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-17'))
;
setIsLoading(false);
setIsLoading(false);
console.error('获取用户数据失败:', err);
console.error('获取用户数据失败:', err);
});
});
}, []);
}, []);
const welcomeMessage = useMemo(() => {
const welcomeMessage = useMemo(() => {
Kopieren
Kopiert
Kopieren
Kopiert
return user
? `
欢迎回来,
${user.name}!`
:
'欢迎来到我们的应用!'
;
return user
? `
${i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-18')}
${user.name}!`
:
i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-19')
;
}, [user]);
}, [user]);
const handleError = useCallback(() => {
const handleError = useCallback(() => {
throw new Error('这是一个故意抛出的错误');
throw new Error('这是一个故意抛出的错误');
}, []);
}, []);
Kopieren
Kopiert
Kopieren
Kopiert
if (isLoading)
return <div>
加载中,请稍候...
</div>;
if (isLoading)
if (error)
return
<div>
错误:
{error}
</div>
;
return <div>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-20')}
</div>;
if (error)
return
(
<div>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-21')}
{error}
</div>
)
;
return (
return (
<ErrorBoundary>
<ErrorBoundary>
<div className="app">
<div className="app">
Kopieren
Kopiert
Kopieren
Kopiert
<Header
title=
"我的 React 应用"
/>
<Header
title=
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-22')}
/>
<main>
<main>
<h2>{welcomeMessage}</h2>
<h2>{welcomeMessage}</h2>
{user && <UserInfo user={user} />}
{user && <UserInfo user={user} />}
<Counter />
<Counter />
<TodoList />
<TodoList />
Kopieren
Kopiert
Kopieren
Kopiert
<button onClick={handleError}>
点击触发错误
</button>
<button onClick={handleError}>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-23')}
</button>
</main>
</main>
<footer>
<footer>
Kopieren
Kopiert
Kopieren
Kopiert
<p>
© 2024 我的 React 应用。保留所有权利。
</p>
<p>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-24')}
</p>
</footer>
</footer>
</div>
</div>
</ErrorBoundary>
</ErrorBoundary>
);
);
};
};
export default App;
export default App;
Gespeicherte Diffs
Originaltext
Datei öffnen
// test.jsx import React, { useState, useEffect, useCallback, useMemo } from 'react'; import PropTypes from 'prop-types'; // 模拟的 API 调用函数 const fetchUserData = () => { return new Promise((resolve) => { setTimeout(() => { resolve({ name: '张三', age: 30, occupation: '软件工程师', }); }, 1000); }); }; // 错误边界组件 class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error) { return { hasError: true, error }; } componentDidCatch(error, errorInfo) { console.error('错误边界捕获到错误:', error, errorInfo); } render() { if (this.state.hasError) { return <h2>很抱歉,出现了错误:{this.state.error.message}</h2>; } return this.props.children; } } // 头部组件 const Header = ({ title }) => ( <header> <h1>{title}</h1> <nav> <ul> <li> <a href="#home">首页</a> </li> <li> <a href="#about">关于我们</a> </li> <li> <a href="#contact">联系方式</a> </li> </ul> </nav> </header> ); Header.propTypes = { title: PropTypes.string.isRequired, }; // 用户信息组件 const UserInfo = ({ user }) => ( <div className="user-info"> <h3>{user.name}的个人信息</h3> <p>年龄:{user.age}</p> <p>职业:{user.occupation}</p> </div> ); // 计数器组件 const Counter = () => { const [count, setCount] = useState(0); const increment = () => setCount((prevCount) => prevCount + 1); const decrement = () => setCount((prevCount) => prevCount - 1); return ( <div> <h3>计数器</h3> <p>当前计数:{count}</p> <button onClick={increment}>增加</button> <button onClick={decrement}>减少</button> </div> ); }; // 待办事项组件 const TodoList = () => { const [todos, setTodos] = useState([]); const [inputValue, setInputValue] = useState(''); const handleInputChange = (e) => setInputValue(e.target.value); const handleSubmit = (e) => { e.preventDefault(); if (inputValue.trim()) { setTodos([ ...todos, { id: Date.now(), text: inputValue, completed: false }, ]); setInputValue(''); } }; const toggleTodo = (id) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, completed: !todo.completed } : todo, ), ); }; return ( <div> <h3>待办事项</h3> <form onSubmit={handleSubmit}> <input type="text" value={inputValue} onChange={handleInputChange} placeholder="输入新的待办事项" /> <button type="submit">添加</button> </form> <ul> {todos.map((todo) => ( <li key={todo.id} onClick={() => toggleTodo(todo.id)} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }} > {todo.text} </li> ))} </ul> </div> ); }; // 主应用组件 const App = () => { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetchUserData() .then((data) => { setUser(data); setIsLoading(false); }) .catch((err) => { setError('获取用户数据时出错'); setIsLoading(false); console.error('获取用户数据失败:', err); }); }, []); const welcomeMessage = useMemo(() => { return user ? `欢迎回来,${user.name}!` : '欢迎来到我们的应用!'; }, [user]); const handleError = useCallback(() => { throw new Error('这是一个故意抛出的错误'); }, []); if (isLoading) return <div>加载中,请稍候...</div>; if (error) return <div>错误:{error}</div>; return ( <ErrorBoundary> <div className="app"> <Header title="我的 React 应用" /> <main> <h2>{welcomeMessage}</h2> {user && <UserInfo user={user} />} <Counter /> <TodoList /> <button onClick={handleError}>点击触发错误</button> </main> <footer> <p>© 2024 我的 React 应用。保留所有权利。</p> </footer> </div> </ErrorBoundary> ); }; export default App;
Bearbeitung
Datei öffnen
import i18n from '@/i18n'; // test.jsx import React, { useState, useEffect, useCallback, useMemo } from 'react'; import PropTypes from 'prop-types'; // 模拟的 API 调用函数 const fetchUserData = () => { return new Promise((resolve) => { setTimeout(() => { resolve({ name: i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-1'), age: 30, occupation: i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-2'), }); }, 1000); }); }; // 错误边界组件 class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error) { return { hasError: true, error }; } componentDidCatch(error, errorInfo) { console.error('错误边界捕获到错误:', error, errorInfo); } render() { if (this.state.hasError) { return ( <h2> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-3')} {this.state.error.message} </h2> ); } return this.props.children; } } // 头部组件 const Header = ({ title }) => ( <header> <h1>{title}</h1> <nav> <ul> <li> <a href="#home"> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-4')} </a> </li> <li> <a href="#about"> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-5')} </a> </li> <li> <a href="#contact"> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-6')} </a> </li> </ul> </nav> </header> ); Header.propTypes = { title: PropTypes.string.isRequired, }; // 用户信息组件 const UserInfo = ({ user }) => ( <div className="user-info"> <h3> {user.name} {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-7')} </h3> <p> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-8')} {user.age} </p> <p> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-9')} {user.occupation} </p> </div> ); // 计数器组件 const Counter = () => { const [count, setCount] = useState(0); const increment = () => setCount((prevCount) => prevCount + 1); const decrement = () => setCount((prevCount) => prevCount - 1); return ( <div> <h3>{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-10')}</h3> <p> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-11')} {count} </p> <button onClick={increment}> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-12')} </button> <button onClick={decrement}> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-13')} </button> </div> ); }; // 待办事项组件 const TodoList = () => { const [todos, setTodos] = useState([]); const [inputValue, setInputValue] = useState(''); const handleInputChange = (e) => setInputValue(e.target.value); const handleSubmit = (e) => { e.preventDefault(); if (inputValue.trim()) { setTodos([ ...todos, { id: Date.now(), text: inputValue, completed: false }, ]); setInputValue(''); } }; const toggleTodo = (id) => { setTodos( todos.map((todo) => todo.id === id ? { ...todo, completed: !todo.completed } : todo, ), ); }; return ( <div> <h3>{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-14')}</h3> <form onSubmit={handleSubmit}> <input type="text" value={inputValue} onChange={handleInputChange} placeholder={i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-15')} /> <button type="submit"> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-16')} </button> </form> <ul> {todos.map((todo) => ( <li key={todo.id} onClick={() => toggleTodo(todo.id)} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }} > {todo.text} </li> ))} </ul> </div> ); }; // 主应用组件 const App = () => { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetchUserData() .then((data) => { setUser(data); setIsLoading(false); }) .catch((err) => { setError(i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-17')); setIsLoading(false); console.error('获取用户数据失败:', err); }); }, []); const welcomeMessage = useMemo(() => { return user ? `${i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-18')}${user.name}!` : i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-19'); }, [user]); const handleError = useCallback(() => { throw new Error('这是一个故意抛出的错误'); }, []); if (isLoading) return <div>{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-20')}</div>; if (error) return ( <div> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-21')} {error} </div> ); return ( <ErrorBoundary> <div className="app"> <Header title={i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-22')} /> <main> <h2>{welcomeMessage}</h2> {user && <UserInfo user={user} />} <Counter /> <TodoList /> <button onClick={handleError}> {i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-23')} </button> </main> <footer> <p>{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-24')}</p> </footer> </div> </ErrorBoundary> ); }; export default App;
Unterschied finden