Diff
checker
Testo
Testo
Immagini
Documenti
Excel
Cartelle
Legal
Enterprise
Applicazione per desktop
Prezzi
Accedi
Scarica Diffchecker Desktop
Confronta il testo
Trova la differenza tra due file di testo
Strumenti
Cronologia
Editor live
Comprimi invariate
Senza a capo
Layout
Diviso
Unificato
Livello di dettaglio
Intelligente
Parola
Carattere
Evidenziazione sintassi
Scegli sintassi
Ignora
Trasforma testo
Vai alla prima modifica
Modifica input
Diffchecker Desktop
Il modo più sicuro per usare Diffchecker. Ottieni l'app Diffchecker Desktop: i tuoi diff non lasciano mai il tuo computer!
Ottieni Desktop
vscode插件i18n-automatically扫描前后jsx的对比图
Creato
2 anni fa
Il diff non scade mai
Eliminare
Esporta
Condividere
Spiegare
24 rimozioni
Linee
Totale
Rimosso
Caratteri
Totale
Rimosso
Per continuare a utilizzare questa funzione, aggiorna a
Diff
checker
Pro
Visualizza prezzi
194 linee
Copia tutti
84 aggiunte
Linee
Totale
Aggiunto
Caratteri
Totale
Aggiunto
Per continuare a utilizzare questa funzione, aggiorna a
Diff
checker
Pro
Visualizza prezzi
237 linee
Copia tutti
Copia
Copiato
Copia
Copiato
// 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({
Copia
Copiato
Copia
Copiato
name:
'张三'
,
name:
i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-1')
,
age: 30,
age: 30,
Copia
Copiato
Copia
Copiato
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) {
Copia
Copiato
Copia
Copiato
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>
Copia
Copiato
Copia
Copiato
<a href="#home">
首页
</a>
<a href="#home">
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-4')}
</a>
</li>
</li>
<li>
<li>
Copia
Copiato
Copia
Copiato
<a href="#about">
关于我们
</a>
<a href="#about">
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-5')}
</a>
</li>
</li>
<li>
<li>
Copia
Copiato
Copia
Copiato
<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">
Copia
Copiato
Copia
Copiato
<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>
Copia
Copiato
Copia
Copiato
<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>
Copia
Copiato
Copia
Copiato
<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}
Copia
Copiato
Copia
Copiato
placeholder=
"输入新的待办事项"
placeholder=
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-15')}
/>
/>
Copia
Copiato
Copia
Copiato
<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) => {
Copia
Copiato
Copia
Copiato
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(() => {
Copia
Copiato
Copia
Copiato
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('这是一个故意抛出的错误');
}, []);
}, []);
Copia
Copiato
Copia
Copiato
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">
Copia
Copiato
Copia
Copiato
<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 />
Copia
Copiato
Copia
Copiato
<button onClick={handleError}>
点击触发错误
</button>
<button onClick={handleError}>
{i18n.t('demoTest-test-jsx-befor-192991598bc5aa541-23')}
</button>
</main>
</main>
<footer>
<footer>
Copia
Copiato
Copia
Copiato
<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;
Diff salvati
Testo originale
Apri file
// 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;
Testo modificato
Apri file
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;
Trovare la differenza